AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Spell Class Reference

#include "Spell.h"

Classes

struct  GOTargetInfo
 
struct  HitTriggerSpell
 
struct  ItemTargetInfo
 

Public Types

typedef std::set< Aura * > UsedSpellMods
 

Public Member Functions

 Spell (Unit *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty, bool skipCheck=false)
 
 ~Spell ()
 
void EffectNULL (SpellEffIndex effIndex)
 
void EffectUnused (SpellEffIndex effIndex)
 
void EffectDistract (SpellEffIndex effIndex)
 
void EffectPull (SpellEffIndex effIndex)
 
void EffectSchoolDMG (SpellEffIndex effIndex)
 
void EffectEnvironmentalDMG (SpellEffIndex effIndex)
 
void EffectInstaKill (SpellEffIndex effIndex)
 
void EffectDummy (SpellEffIndex effIndex)
 
void EffectTeleportUnits (SpellEffIndex effIndex)
 
void EffectApplyAura (SpellEffIndex effIndex)
 
void EffectSendEvent (SpellEffIndex effIndex)
 
void EffectPowerBurn (SpellEffIndex effIndex)
 
void EffectPowerDrain (SpellEffIndex effIndex)
 
void EffectHeal (SpellEffIndex effIndex)
 
void EffectBind (SpellEffIndex effIndex)
 
void EffectHealthLeech (SpellEffIndex effIndex)
 
void EffectQuestComplete (SpellEffIndex effIndex)
 
void EffectCreateItem (SpellEffIndex effIndex)
 
void EffectCreateItem2 (SpellEffIndex effIndex)
 
void EffectCreateRandomItem (SpellEffIndex effIndex)
 
void EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectProficiency (SpellEffIndex effIndex)
 
void EffectApplyAreaAura (SpellEffIndex effIndex)
 
void EffectSummonType (SpellEffIndex effIndex)
 
void EffectLearnSpell (SpellEffIndex effIndex)
 
void EffectDispel (SpellEffIndex effIndex)
 
void EffectDualWield (SpellEffIndex effIndex)
 
void EffectPickPocket (SpellEffIndex effIndex)
 
void EffectAddFarsight (SpellEffIndex effIndex)
 
void EffectUntrainTalents (SpellEffIndex effIndex)
 
void EffectHealMechanical (SpellEffIndex effIndex)
 
void EffectJump (SpellEffIndex effIndex)
 
void EffectJumpDest (SpellEffIndex effIndex)
 
void EffectLeapBack (SpellEffIndex effIndex)
 
void EffectQuestClear (SpellEffIndex effIndex)
 
void EffectTeleUnitsFaceCaster (SpellEffIndex effIndex)
 
void EffectLearnSkill (SpellEffIndex effIndex)
 
void EffectAddHonor (SpellEffIndex effIndex)
 
void EffectTradeSkill (SpellEffIndex effIndex)
 
void EffectEnchantItemPerm (SpellEffIndex effIndex)
 
void EffectEnchantItemTmp (SpellEffIndex effIndex)
 
void EffectTameCreature (SpellEffIndex effIndex)
 
void EffectSummonPet (SpellEffIndex effIndex)
 
void EffectLearnPetSpell (SpellEffIndex effIndex)
 
void EffectWeaponDmg (SpellEffIndex effIndex)
 
void EffectForceCast (SpellEffIndex effIndex)
 
void EffectTriggerSpell (SpellEffIndex effIndex)
 
void EffectTriggerMissileSpell (SpellEffIndex effIndex)
 
void EffectThreat (SpellEffIndex effIndex)
 
void EffectHealMaxHealth (SpellEffIndex effIndex)
 
void EffectInterruptCast (SpellEffIndex effIndex)
 
void EffectSummonObjectWild (SpellEffIndex effIndex)
 
void EffectScriptEffect (SpellEffIndex effIndex)
 
void EffectSanctuary (SpellEffIndex effIndex)
 
void EffectAddComboPoints (SpellEffIndex effIndex)
 
void EffectDuel (SpellEffIndex effIndex)
 
void EffectStuck (SpellEffIndex effIndex)
 
void EffectSummonPlayer (SpellEffIndex effIndex)
 
void EffectActivateObject (SpellEffIndex effIndex)
 
void EffectApplyGlyph (SpellEffIndex effIndex)
 
void EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectLeap (SpellEffIndex effIndex)
 
void EffectTransmitted (SpellEffIndex effIndex)
 
void EffectDisEnchant (SpellEffIndex effIndex)
 
void EffectInebriate (SpellEffIndex effIndex)
 
void EffectFeedPet (SpellEffIndex effIndex)
 
void EffectDismissPet (SpellEffIndex effIndex)
 
void EffectReputation (SpellEffIndex effIndex)
 
void EffectForceDeselect (SpellEffIndex effIndex)
 
void EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectChargeDest (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectMilling (SpellEffIndex effIndex)
 
void EffectRenamePet (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPullTowards (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectResurrectPet (SpellEffIndex effIndex)
 
void EffectDestroyAllTotems (SpellEffIndex effIndex)
 
void EffectDurabilityDamage (SpellEffIndex effIndex)
 
void EffectSkill (SpellEffIndex effIndex)
 
void EffectTaunt (SpellEffIndex effIndex)
 
void EffectDurabilityDamagePCT (SpellEffIndex effIndex)
 
void EffectModifyThreatPercent (SpellEffIndex effIndex)
 
void EffectResurrectNew (SpellEffIndex effIndex)
 
void EffectAddExtraAttacks (SpellEffIndex effIndex)
 
void EffectSpiritHeal (SpellEffIndex effIndex)
 
void EffectSkinPlayerCorpse (SpellEffIndex effIndex)
 
void EffectStealBeneficialBuff (SpellEffIndex effIndex)
 
void EffectUnlearnSpecialization (SpellEffIndex effIndex)
 
void EffectHealPct (SpellEffIndex effIndex)
 
void EffectEnergizePct (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectSummonRaFFriend (SpellEffIndex effIndex)
 
void EffectKillCreditPersonal (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectQuestStart (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectGameObjectDamage (SpellEffIndex effIndex)
 
void EffectGameObjectRepair (SpellEffIndex effIndex)
 
void EffectGameObjectSetDestructionState (SpellEffIndex effIndex)
 
void EffectActivateRune (SpellEffIndex effIndex)
 
void EffectCreateTamedPet (SpellEffIndex effIndex)
 
void EffectDiscoverTaxi (SpellEffIndex effIndex)
 
void EffectTitanGrip (SpellEffIndex effIndex)
 
void EffectEnchantItemPrismatic (SpellEffIndex effIndex)
 
void EffectPlayMusic (SpellEffIndex effIndex)
 
void EffectSpecCount (SpellEffIndex effIndex)
 
void EffectActivateSpec (SpellEffIndex effIndex)
 
void EffectPlaySound (SpellEffIndex effIndex)
 
void EffectRemoveAura (SpellEffIndex effIndex)
 
void EffectCastButtons (SpellEffIndex effIndex)
 
void EffectRechargeManaGem (SpellEffIndex effIndex)
 
void InitExplicitTargets (SpellCastTargets const &targets)
 
void SelectExplicitTargets ()
 
void SelectSpellTargets ()
 
void SelectEffectImplicitTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
 
void SelectImplicitChannelTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitNearbyTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitConeTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitAreaTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
 
void SelectImplicitCasterDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitDestDestTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitCasterObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitTargetObjectTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectImplicitChainTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
 
void SelectImplicitTrajTargets (SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void SelectEffectTypeImplicitTargets (uint8 effIndex)
 
uint32 GetSearcherTypeMask (SpellTargetObjectTypes objType, ConditionList *condList)
 
template<class SEARCHER >
void SearchTargets (SEARCHER &searcher, uint32 containerMask, Unit *referer, Position const *pos, float radius)
 
WorldObjectSearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet. More...
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

static void WriteCastResultInfo (WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
 
static void SendCastResult (Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
 

Public Attributes

SpellInfo const *const m_spellInfo
 
Itemm_CastItem
 
Itemm_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unitm_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

bool HasGlobalCooldown () const
 
void TriggerGlobalCooldown ()
 
void CancelGlobalCooldown ()
 
void SendLoot (ObjectGuid guid, LootType loottype)
 
std::string GetDebugInfo () const
 
bool isDelayableNoMore ()
 
void prepareDataForTriggerSystem (AuraEffect const *triggeredByAura)
 
void AddUnitTarget (Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
 
void AddGOTarget (GameObject *target, uint32 effectMask)
 
void AddItemTarget (Item *item, uint32 effectMask)
 
void AddDestTarget (SpellDestination const &dest, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
SpellMissInfo DoSpellHitOnUnit (Unit *unit, uint32 effectMask, bool scaleAura)
 
void DoTriggersOnSpellHit (Unit *unit, uint8 effMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool UpdateChanneledTargetList ()
 
bool IsValidDeadOrAliveTarget (Unit const *target) const
 
void HandleLaunchPhase ()
 
void DoAllEffectOnLaunchTarget (TargetInfo &targetInfo, float *multiplier)
 
void PrepareTargetProcessing ()
 
void FinishTargetProcessing ()
 
void InitEffectExecuteData (uint8 effIndex)
 
void CheckEffectExecuteData ()
 
void CallScriptBeforeCastHandlers ()
 
void CallScriptOnCastHandlers ()
 
void CallScriptAfterCastHandlers ()
 
SpellCastResult CallScriptCheckCastHandlers ()
 
void PrepareScriptHitHandlers ()
 
bool CallScriptEffectHandlers (SpellEffIndex effIndex, SpellEffectHandleMode mode)
 
void CallScriptBeforeHitHandlers (SpellMissInfo missInfo)
 
void CallScriptOnHitHandlers ()
 
void CallScriptAfterHitHandlers ()
 
void CallScriptObjectAreaTargetSelectHandlers (std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptObjectTargetSelectHandlers (WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
void CallScriptDestinationTargetSelectHandlers (SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
 
bool CheckScriptEffectImplicitTargets (uint32 effIndex, uint32 effIndexToCheck)
 
bool CanExecuteTriggersOnHit (uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
 
void PrepareTriggersExecutedOnHit ()
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
 
void CalculateJumpSpeeds (uint8 i, float dist, float &speedxy, float &speedz)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
int32 m_channeledDuration
 
bool m_canReflect
 
uint8 m_spellFlags
 
bool m_autoRepeat
 
uint8 m_runesState
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
uint64 m_delayTrajectory
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
WorldLocationdestTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Auram_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
SpellDestination m_destTargets [MAX_SPELL_EFFECTS]
 
bool _scriptsLoaded
 
std::list< SpellScript * > m_loadedScripts
 
HitTriggerSpellList m_hitTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
SpellEvent_spellEvent
 
TriggerCastFlags _triggeredCastFlags
 
TriggeredByAuraSpellData m_triggeredByAuraSpell
 
bool m_skipCheck
 
uint8 m_auraScaleMask
 
std::unique_ptr< PathGeneratorm_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBufferm_effectExecuteData [MAX_SPELL_EFFECTS]
 

Friends

class SpellScript
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

typedef std::list<HitTriggerSpell> Spell::HitTriggerSpellList
protected

◆ UsedSpellMods

typedef std::set<Aura*> Spell::UsedSpellMods

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
567 :
568 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
569 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
571{
573 m_skipCheck = skipCheck;
574 m_selfContainer = nullptr;
576 m_executedCurrently = false;
579 m_comboTarget = nullptr;
580 m_delayStart = 0;
582
584 m_auraScaleMask = 0;
585 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
586
587 // Get data for type of attack
588 switch (m_spellInfo->DmgClass)
589 {
593 else
595 break;
598 break;
599 default:
600 // Wands
603 else
605 break;
606 }
607
608 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
609
611 // wand case
614 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
615
616 if (originalCasterGUID)
617 m_originalCasterGUID = originalCasterGUID;
618 else
620
623 else
624 {
627 m_originalCaster = nullptr;
628 }
629
631 _triggeredCastFlags = triggerFlags;
632 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
634
635 m_CastItem = nullptr;
636
637 unitTarget = nullptr;
638 itemTarget = nullptr;
639 gameObjTarget = nullptr;
640 destTarget = nullptr;
641 damage = 0;
645 m_damage = 0;
646 m_healing = 0;
647 m_procAttacker = 0;
648 m_procVictim = 0;
649 m_procEx = 0;
650 focusObject = nullptr;
651 m_cast_count = 0;
652 m_glyphIndex = 0;
653 m_preCastSpell = 0;
654 m_spellAura = nullptr;
655 _scriptsLoaded = false;
656
657 //Auto Shot & Shoot (wand)
659
660 m_runesState = 0;
661 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
662 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
663 m_timer = 0; // will set to castime in prepare
664 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
665 m_immediateHandled = false;
666
668
670
671 // Determine if spell can be reflected back to the caster
672 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
676
678 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
679
680 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
682
683 // xinef:
684 _spellTargetsSelected = false;
685
686 m_weaponItem = nullptr;
687}
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:1636
@ DIMINISHING_NONE
Definition: SharedDefines.h:3258
@ SPELL_EFFECT_DISPEL
Definition: SharedDefines.h:816
#define CLASSMASK_WAND_USERS
Definition: SharedDefines.h:174
@ SPELL_ATTR2_AUTO_REPEAT
Definition: SharedDefines.h:461
@ SPELL_ATTR1_NO_REFLECTION
Definition: SharedDefines.h:426
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition: SharedDefines.h:517
@ SPELL_DAMAGE_CLASS_RANGED
Definition: SharedDefines.h:1548
@ SPELL_DAMAGE_CLASS_MAGIC
Definition: SharedDefines.h:1546
@ SPELL_DAMAGE_CLASS_MELEE
Definition: SharedDefines.h:1547
@ SPELL_CUSTOM_ERROR_NONE
Definition: SharedDefines.h:1143
@ SPELL_ATTR0_IS_ABILITY
Definition: SharedDefines.h:386
@ SPELL_ATTR0_NO_IMMUNITIES
Definition: SharedDefines.h:411
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition: SharedDefines.h:537
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition: SharedDefines.h:622
SpellSchoolMask
Definition: SharedDefines.h:295
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition: Spell.h:235
@ SPELL_FLAG_NORMAL
Definition: Spell.h:83
@ SPELL_STATE_NULL
Definition: Spell.h:225
TriggerCastFlags
Definition: SpellDefines.h:129
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition: SpellDefines.h:138
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition: SpellDefines.h:136
#define sSpellMgr
Definition: SpellMgr.h:825
@ OFF_ATTACK
Definition: Unit.h:210
@ BASE_ATTACK
Definition: Unit.h:209
@ RANGED_ATTACK
Definition: Unit.h:211
@ DIMINISHING_LEVEL_1
Definition: Unit.h:263
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:199
Definition: Item.h:220
bool IsPlayer() const
Definition: Object.h:197
Player * ToPlayer()
Definition: Object.h:198
bool IsInWorld() const
Definition: Object.h:104
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:109
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: PlayerStorage.cpp:488
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1211
uint32 getClassMask() const
Definition: Unit.h:802
Definition: Spell.h:96
Definition: Spell.h:213
Unit * m_comboTarget
Definition: Spell.h:544
int8 m_comboPointGain
Definition: Spell.h:545
GameObject * gameObjTarget
Definition: Spell.h:655
bool m_referencedFromCurrentSpell
Definition: Spell.h:646
bool m_canReflect
Definition: Spell.h:622
uint32 m_procVictim
Definition: Spell.h:677
Unit * m_originalCaster
Definition: Spell.h:610
bool m_needComboPoints
Definition: Spell.h:648
uint64 m_delayStart
Definition: Spell.h:640
bool _scriptsLoaded
Definition: Spell.h:728
TriggerCastFlags _triggeredCastFlags
Definition: Spell.h:769
int32 damage
Definition: Spell.h:657
SpellEffectHandleMode effectHandleMode
Definition: Spell.h:658
int32 m_channeledDuration
Definition: Spell.h:621
Aura * m_spellAura
Definition: Spell.h:660
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition: Spell.h:703
Unit *const m_caster
Definition: Spell.h:604
uint8 m_delayAtDamageCount
Definition: Spell.h:629
WeaponAttackType m_attackType
Definition: Spell.h:618
bool m_immediateHandled
Definition: Spell.h:643
uint32 m_spellState
Definition: Spell.h:765
ObjectGuid m_originalCasterGUID
Definition: Spell.h:608
void CleanupTargetList()
Definition: Spell.cpp:2371
int32 m_timer
Definition: Spell.h:766
int32 m_casttime
Definition: Spell.h:620
Item * itemTarget
Definition: Spell.h:654
uint8 m_cast_count
Definition: Spell.h:526
int32 m_damage
Definition: Spell.h:670
bool m_executedCurrently
Definition: Spell.h:647
DiminishingLevels m_diminishLevel
Definition: Spell.h:663
float m_damageMultipliers[3]
Definition: Spell.h:650
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition: Spell.h:783
uint8 m_auraScaleMask
Definition: Spell.h:777
SpellCustomErrors m_customError
Definition: Spell.h:530
uint8 m_spellFlags
Definition: Spell.h:624
bool m_skipCheck
Definition: Spell.h:776
int32 m_healing
Definition: Spell.h:671
uint32 m_glyphIndex
Definition: Spell.h:527
uint8 m_channelTargetEffectMask
Definition: Spell.h:685
Item * m_weaponItem
Definition: Spell.h:524
Unit * unitTarget
Definition: Spell.h:653
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:617
SpellEvent * _spellEvent
Definition: Spell.h:768
bool _spellTargetsSelected
Definition: Spell.h:781
uint32 m_preCastSpell
Definition: Spell.h:528
WorldLocation * destTarget
Definition: Spell.h:656
Spell ** m_selfContainer
Definition: Spell.h:612
uint8 m_applyMultiplierMask
Definition: Spell.h:649
DiminishingGroup m_diminishGroup
Definition: Spell.h:664
uint32 m_procEx
Definition: Spell.h:678
Item * m_CastItem
Definition: Spell.h:523
SpellValue *const m_spellValue
Definition: Spell.h:606
int32 m_powerCost
Definition: Spell.h:619
uint32 m_procAttacker
Definition: Spell.h:676
GameObject * focusObject
Definition: Spell.h:667
SpellInfo const *const m_spellInfo
Definition: Spell.h:522
uint8 m_runesState
Definition: Spell.h:627
bool m_autoRepeat
Definition: Spell.h:626
bool IsPassive() const
Definition: SpellInfo.cpp:1098
bool NeedsComboPoints() const
Definition: SpellInfo.cpp:1266
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:415
bool HasEffect(SpellEffects effect) const
Definition: SpellInfo.cpp:876
bool IsPositive() const
Definition: SpellInfo.cpp:1237
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1283
uint32 DmgClass
Definition: SpellInfo.h:389
bool IsRangedWeaponSpell() const
Definition: SpellInfo.cpp:1276
Definition: ByteBuffer.h:70

References _scriptsLoaded, _spellTargetsSelected, _triggeredCastFlags, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), damage, destTarget, DIMINISHING_LEVEL_1, DIMINISHING_NONE, SpellInfo::DmgClass, effectHandleMode, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_damageMultipliers, m_delayAtDamageCount, m_delayStart, m_destTargets, m_diminishGroup, m_diminishLevel, m_effectExecuteData, m_executedCurrently, m_glyphIndex, m_healing, m_immediateHandled, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_preCastSpell, m_procAttacker, m_procEx, m_procVictim, m_referencedFromCurrentSpell, m_runesState, m_selfContainer, m_skipCheck, m_spellAura, m_spellFlags, m_spellInfo, m_spellSchoolMask, m_spellState, m_timer, m_weaponItem, MAX_SPELL_EFFECTS, SpellInfo::NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR1_NO_REFLECTION, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING, SPELL_CUSTOM_ERROR_NONE, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_FLAG_NORMAL, SPELL_STATE_NULL, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

◆ ~Spell()

Spell::~Spell ( )
690{
691 // unload scripts
692 while (!m_loadedScripts.empty())
693 {
694 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
695 (*itr)->_Unload();
696 delete (*itr);
697 m_loadedScripts.erase(itr);
698 }
699
701 {
702 // Clean the reference to avoid later crash.
703 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
704 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
705 *m_selfContainer = nullptr;
706 }
707
708 delete m_spellValue;
709
711}
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157
void CheckEffectExecuteData()
Definition: Spell.cpp:8491
std::list< SpellScript * > m_loadedScripts
Definition: Spell.h:743
uint32 Id
Definition: SpellInfo.h:320

References CheckEffectExecuteData(), SpellInfo::Id, LOG_ERROR, m_loadedScripts, m_referencedFromCurrentSpell, m_selfContainer, m_spellInfo, and m_spellValue.

Member Function Documentation

◆ _cast()

void Spell::_cast ( bool  skipCheck)

Not own traded item (in trader trade slot) req. reagents including triggered spell case

3808{
3809 // update pointers base at GUIDs to prevent access to non-existed already object
3810 if (!UpdatePointers())
3811 {
3812 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3813 cancel();
3814 return;
3815 }
3816
3817 // cancel at lost explicit target during cast
3819 {
3820 cancel();
3821 return;
3822 }
3823
3824 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3826 {
3828 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3830
3831 if (Unit* charm = m_caster->GetCharm())
3832 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3833 }
3834
3835 if (Player* playerCaster = m_caster->ToPlayer())
3836 {
3837 // now that we've done the basic check, now run the scripts
3838 // should be done before the spell is actually executed
3839 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3840
3841 // As of 3.0.2 pets begin attacking their owner's target immediately
3842 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3843 // This prevents spells such as Hunter's Mark from triggering pet attack
3844 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3846 if (!playerCaster->m_Controlled.empty())
3847 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3848 if (Unit* pet = *itr)
3849 if (pet->IsAlive() && pet->IsCreature())
3850 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3851 }
3852
3854
3858
3860
3861 Player* modOwner = m_caster->GetSpellModOwner();
3862 // skip check if done already (for instant cast spells for example)
3863 if (!skipCheck)
3864 {
3865 SpellCastResult castResult = CheckCast(false);
3866 if (castResult != SPELL_CAST_OK)
3867 {
3868 SendCastResult(castResult);
3869 SendInterrupted(0);
3870
3871 finish(false);
3872 SetExecutedCurrently(false);
3873 return;
3874 }
3875
3876 // additional check after cast bar completes (must not be in CheckCast)
3877 // if trade not complete then remember it in trade data
3879 {
3880 if (m_caster->IsPlayer())
3881 {
3882 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3883 {
3884 if (!my_trade->IsInAcceptProcess())
3885 {
3886 // Spell will be casted at completing the trade. Silently ignore at this place
3887 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3889 SendInterrupted(0);
3890
3891 finish(false);
3892 SetExecutedCurrently(false);
3893 return;
3894 }
3895 }
3896 }
3897 }
3898 }
3899
3900 if (modOwner)
3901 modOwner->SetSpellModTakingSpell(this, true);
3902
3905
3906 if (modOwner)
3907 modOwner->SetSpellModTakingSpell(this, false);
3908
3909 // Spell may be finished after target map check
3911 {
3912 SendInterrupted(0);
3913 finish(false);
3914 SetExecutedCurrently(false);
3915 return;
3916 }
3917
3918 if (modOwner)
3919 modOwner->SetSpellModTakingSpell(this, true);
3920
3922
3924
3925 if (modOwner)
3926 modOwner->SetSpellModTakingSpell(this, false);
3927
3928 // traded items have trade slot instead of guid in m_itemTargetGUID
3929 // set to real guid to be sent later to the client
3931
3932 if (m_caster->IsPlayer())
3933 {
3935 {
3938 }
3939
3941 }
3942
3944 {
3945 // Powers have to be taken before SendSpellGo
3946 TakePower();
3947 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3948 }
3949 else if (Item* targetItem = m_targets.GetItemTarget())
3950 {
3952 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3953 TakeReagents();
3954 }
3955
3957
3958 // CAST SPELL
3959 if (modOwner)
3960 modOwner->SetSpellModTakingSpell(this, true);
3961
3963
3965
3966 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3967 SendSpellGo();
3968
3969 if (modOwner)
3970 modOwner->SetSpellModTakingSpell(this, false);
3971
3972 if (m_originalCaster)
3973 {
3974 // Handle procs on cast
3975 uint32 procAttacker = m_procAttacker;
3976 if (!procAttacker)
3977 {
3978 bool IsPositive = m_spellInfo->IsPositive();
3980 {
3982 }
3983 else
3984 {
3986 }
3987 }
3988
3989 uint32 procEx = PROC_EX_NORMAL_HIT;
3990
3991 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3992 {
3993 if (ihit->missCondition != SPELL_MISS_NONE)
3994 {
3995 continue;
3996 }
3997
3998 if (!ihit->crit)
3999 {
4000 continue;
4001 }
4002
4003 procEx |= PROC_EX_CRITICAL_HIT;
4004 break;
4005 }
4006
4009 }
4010
4011 if (modOwner)
4012 modOwner->SetSpellModTakingSpell(this, true);
4013
4015 if (resetAttackTimers)
4016 {
4018 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4019 {
4020 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4021 {
4022 resetAttackTimers = false;
4023 break;
4024 }
4025 }
4026 }
4027
4028 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4029 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4030 {
4031 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4032 // in case delayed spell remove item at cast delay start
4033 TakeCastItem();
4034
4035 // Okay, maps created, now prepare flags
4036 m_immediateHandled = false;
4038 SetDelayStart(0);
4039
4042
4043 // remove all applied mods at this point
4044 // dont allow user to use them twice in case spell did not reach current target
4045 if (modOwner)
4046 modOwner->RemoveSpellMods(this);
4047
4048 // Xinef: why do we keep focus after spell is sent to air?
4049 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4050 // Xinef: we get focused to it out of nowhere...
4051 if (Creature* creatureCaster = m_caster->ToCreature())
4052 creatureCaster->ReleaseFocus(this);
4053 }
4054 else
4055 {
4056 // Immediate spell, no big deal
4058 }
4059
4060 if (resetAttackTimers)
4061 {
4062 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4063 {
4064 resetAttackTimers = false;
4065 }
4066
4067 if (resetAttackTimers)
4068 {
4070
4072 {
4074 }
4075
4077 }
4078 }
4079
4081
4082 if (modOwner)
4083 modOwner->SetSpellModTakingSpell(this, false);
4084
4085 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4086 {
4087 for (int32 id : *spell_triggered)
4088 {
4089 if (id < 0)
4091 else
4093 }
4094 }
4095
4096 // Interrupt Spell casting
4097 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4099 if (Unit* target = m_targets.GetUnitTarget())
4100 if (target->IsCreature())
4101 m_caster->CastSpell(target, 32747, true);
4102
4103 // xinef: start combat at cast for delayed spells, only for explicit target
4104 if (Unit* target = m_targets.GetUnitTarget())
4107 m_caster->CombatStartOnCast(target, !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_TARGET_PROCS), GetDelayMoment() + 500); // xinef: increase this time so we dont leave and enter combat in a moment
4108
4109 if (m_caster->IsPlayer())
4112
4113 SetExecutedCurrently(false);
4114}
std::int32_t int32
Definition: Define.h:103
@ ACHIEVEMENT_TIMED_TYPE_ITEM
Definition: DBCEnums.h:115
@ ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM
Definition: DBCEnums.h:155
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL
Definition: DBCEnums.h:143
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition: SharedDefines.h:652
@ SPELL_EFFECT_SUMMON_PET
Definition: SharedDefines.h:834
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition: SharedDefines.h:473
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition: SharedDefines.h:419
@ SPELL_ATTR3_SUPPRESS_TARGET_PROCS
Definition: SharedDefines.h:510
@ SPELL_DAMAGE_CLASS_NONE
Definition: SharedDefines.h:1545
@ SPELL_MISS_NONE
Definition: SharedDefines.h:1519
SpellCastResult
Definition: SharedDefines.h:948
@ SPELL_FAILED_DONT_REPORT
Definition: SharedDefines.h:976
@ SPELL_CAST_OK
Definition: SharedDefines.h:1138
@ TARGET_FLAG_TRADE_ITEM
Definition: SpellInfo.h:58
@ TARGET_FLAG_UNIT
Definition: SpellInfo.h:47
@ SPELL_STATE_DELAYED
Definition: Spell.h:230
@ SPELL_STATE_FINISHED
Definition: Spell.h:228
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition: SpellDefines.h:133
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition: SpellDefines.h:134
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition: SpellDefines.h:140
@ SPELL_AURA_MOD_CHARM
Definition: SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition: SpellAuraDefines.h:335
@ SPELL_AURA_BIND_SIGHT
Definition: SpellAuraDefines.h:64
@ PROC_EX_CRITICAL_HIT
Definition: SpellMgr.h:195
@ PROC_EX_NORMAL_HIT
Definition: SpellMgr.h:194
@ PROC_SPELL_PHASE_CAST
Definition: SpellMgr.h:243
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:128
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:122
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:125
@ PROC_FLAG_NONE
Definition: SpellMgr.h:105
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:131
@ CHEAT_COOLDOWN
Definition: Player.h:1001
@ UNIT_STATE_CASTING
Definition: UnitDefines.h:164
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
#define sScriptMgr
Definition: ScriptMgr.h:709
Definition: Creature.h:43
uint32 GetEntry() const
Definition: Object.h:112
bool IsCreature() const
Definition: Object.h:201
Creature * ToCreature()
Definition: Object.h:202
Definition: Pet.h:41
Definition: Player.h:1064
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition: PlayerUpdates.cpp:2130
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition: Player.cpp:10087
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition: Player.cpp:13931
void RemoveSpellMods(Spell *spell)
Definition: Player.cpp:10019
Pet * GetPet() const
Definition: Player.cpp:8916
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1178
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:9067
TradeData * GetTradeData() const
Definition: Player.h:1370
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3511
Definition: TradeData.h:36
Definition: Unit.h:630
bool HasOffhandWeaponForAttack() const
Definition: Unit.h:934
void ClearUnitState(uint32 f)
Definition: Unit.h:702
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1349
Unit * GetCharm() const
Definition: Unit.cpp:10666
Player * GetSpellModOwner() const
Definition: Unit.cpp:16573
void CombatStartOnCast(Unit *target, bool initialAggro=true, uint32 duration=0)
Definition: Unit.cpp:13700
bool IsPet() const
Definition: Unit.h:754
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4099
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1167
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4909
static void ProcDamageAndSpell(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition: Unit.cpp:6378
bool HasUnitState(const uint32 f) const
Definition: Unit.h:701
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10241
bool IsControlledByPlayer() const
Definition: Unit.h:1232
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:646
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20517
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:642
WorldObject * GetObjectTarget() const
Definition: Spell.cpp:311
void UpdateTradeSlotItem()
Definition: Spell.cpp:348
ObjectGuid GetObjectTargetGUID() const
Definition: Spell.cpp:316
Item * GetItemTarget() const
Definition: Spell.h:141
uint32 GetTargetMask() const
Definition: Spell.h:119
Unit * GetUnitTarget() const
Definition: Spell.cpp:232
int8 effectIndex
Definition: Spell.h:281
SpellInfo const * spellInfo
Definition: Spell.h:280
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:577
void CallScriptAfterCastHandlers()
Definition: Spell.cpp:8545
void PrepareTriggersExecutedOnHit()
Definition: Spell.cpp:8751
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition: Spell.h:555
SpellCastTargets m_targets
Definition: Spell.h:529
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition: Spell.h:774
void handle_immediate()
Definition: Spell.cpp:4116
void SendSpellGo()
Definition: Spell.cpp:4798
void TakeReagents()
Definition: Spell.cpp:5532
void SetExecutedCurrently(bool yes)
Definition: Spell.h:563
void SendInterrupted(uint8 result)
Definition: Spell.cpp:5175
void PrepareScriptHitHandlers()
Definition: Spell.cpp:8577
void CallScriptOnCastHandlers()
Definition: Spell.cpp:8532
void cancel(bool bySelf=false)
Definition: Spell.cpp:3719
void SendSpellCooldown()
Definition: Spell.cpp:4356
void CallScriptBeforeCastHandlers()
Definition: Spell.cpp:8519
void HandleLaunchPhase()
Definition: Spell.cpp:8232
bool UpdatePointers()
Definition: Spell.cpp:7862
void SetDelayStart(uint64 m_time)
Definition: Spell.h:565
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:684
void SelectSpellTargets()
Definition: Spell.cpp:815
void TakePower()
Definition: Spell.cpp:5316
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5654
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4670
uint64 GetDelayMoment() const
Definition: Spell.h:566
void TakeCastItem()
Definition: Spell.cpp:5253
bool IsAutoActionResetSpell() const
Definition: Spell.cpp:8076
void finish(bool ok=true)
Definition: Spell.cpp:4483
float Speed
Definition: SpellInfo.h:370
bool IsChanneled() const
Definition: SpellInfo.cpp:1256
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2352
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:893

References _spellTargetsSelected, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_TIMED_TYPE_ITEM, BASE_ATTACK, SpellInfo::CalcCastTime(), CallScriptAfterCastHandlers(), CallScriptBeforeCastHandlers(), CallScriptOnCastHandlers(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), Unit::ClearUnitState(), Unit::CombatStartOnCast(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, finish(), Unit::GetAuraEffectsByType(), Unit::GetCharm(), Player::GetCommandStatus(), GetDelayMoment(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), Player::GetPet(), GetSpellInfo(), Unit::GetSpellModOwner(), SpellCastTargets::GetTargetMask(), Player::GetTradeData(), SpellCastTargets::GetUnitTarget(), handle_immediate(), HandleLaunchPhase(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), SpellInfo::HasEffect(), Unit::HasOffhandWeaponForAttack(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, IsAutoActionResetSpell(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsNonMeleeSpellCast(), Unit::IsPet(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_CastItem, m_casttime, m_immediateHandled, m_originalCaster, m_procAttacker, m_spellInfo, m_spellState, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, OFF_ATTACK, PET_SAVE_AS_CURRENT, PrepareScriptHitHandlers(), PrepareTriggersExecutedOnHit(), PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_CAST, Unit::ProcDamageAndSpell(), RANGED_ATTACK, Unit::RemoveAurasDueToSpell(), Player::RemovePet(), Player::RemoveSpellCooldown(), Player::RemoveSpellMods(), Unit::resetAttackTimer(), SelectSpellTargets(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), Player::SetSpellModTakingSpell(), SpellInfo::Speed, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_AURA_BIND_SIGHT, SPELL_AURA_IGNORE_MELEE_RESET, SPELL_AURA_MOD_CHARM, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_SUMMON_PET, SPELL_FAILED_DONT_REPORT, SPELL_MISS_NONE, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, TriggeredByAuraSpellData::spellInfo, sScriptMgr, sSpellMgr, Player::StartTimedAchievement(), TakeCastItem(), TakePower(), TakeReagents(), TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_IGNORE_CAST_ITEM, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SET_FACING, UNIT_STATE_CASTING, Player::UpdateAchievementCriteria(), UpdatePointers(), and SpellCastTargets::UpdateTradeSlotItem().

Referenced by cast().

◆ _handle_finish_phase()

void Spell::_handle_finish_phase ( )
4282{
4283 // Take for real after all targets are processed
4285 {
4287 }
4288
4289 // Real add combo points from effects
4291 {
4292 // remove Premed-like effects unless they were caused by ourselves
4293 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4295 {
4297 }
4298
4300 }
4301
4303 {
4305 }
4306
4309 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4310 {
4311 // Xinef: Properly clear infinite cooldowns in some cases
4312 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4315 }
4316
4317 // Handle procs on finish
4318 if (m_originalCaster)
4319 {
4320 uint32 procAttacker = m_procAttacker;
4321 if (!procAttacker)
4322 {
4323 bool IsPositive = m_spellInfo->IsPositive();
4325 {
4327 }
4328 else
4329 {
4331 }
4332 }
4333
4334 uint32 procEx = PROC_EX_NORMAL_HIT;
4335 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4336 {
4337 if (ihit->missCondition != SPELL_MISS_NONE)
4338 {
4339 continue;
4340 }
4341
4342 if (!ihit->crit)
4343 {
4344 continue;
4345 }
4346
4347 procEx |= PROC_EX_CRITICAL_HIT;
4348 break;
4349 }
4350
4353 }
4354}
@ SPELL_EFFECT_ADD_EXTRA_ATTACKS
Definition: SharedDefines.h:797
@ SPELL_AURA_RETAIN_COMBO_POINTS
Definition: SpellAuraDefines.h:211
@ PROC_SPELL_PHASE_FINISH
Definition: SpellMgr.h:245
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition: Player.cpp:11115
void SetLastExtraAttackSpell(uint32 spellId)
Definition: Unit.h:953
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:10616
void ClearComboPoints()
Definition: Unit.cpp:16860
void AddComboPoints(Unit *target, int8 count)
Definition: Unit.cpp:16834
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5110
bool IsAutoRepeat() const
Definition: Spell.h:550
bool IsNextMeleeSwingSpell() const
Definition: Spell.cpp:8066
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1212

References Unit::AddComboPoints(), BASE_ATTACK, Unit::ClearComboPoints(), SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetGUID(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), Object::IsPlayer(), SpellInfo::IsPositive(), m_caster, m_comboPointGain, m_comboTarget, m_needComboPoints, m_originalCaster, m_procAttacker, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, PROC_EX_CRITICAL_HIT, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_NONE, PROC_SPELL_PHASE_FINISH, Unit::ProcDamageAndSpell(), Unit::RemoveAurasByType(), Player::SendCooldownEvent(), Unit::SetLastExtraAttackSpell(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4254{
4255 m_spellAura = nullptr;
4256 // initialize Diminishing Returns Data
4259
4260 // handle some immediate features of the spell here
4262
4264
4265 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4266 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4267 {
4268 // don't do anything for empty effect
4269 if (!m_spellInfo->Effects[j].IsEffect())
4270 continue;
4271
4272 // call effect handlers to handle destination hit
4273 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4274 }
4275
4276 // process items
4277 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4278 DoAllEffectOnTarget(&(*ihit));
4279}
@ SPELL_EFFECT_HANDLE_HIT
Definition: Spell.h:237
void HandleThreatSpells()
Definition: Spell.cpp:5581
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition: Spell.cpp:5628
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:701
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:2609
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:393

References DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellInfo::Effects, HandleEffects(), HandleThreatSpells(), m_diminishGroup, m_diminishLevel, m_spellAura, m_spellInfo, m_UniqueItemInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), and SPELL_EFFECT_HANDLE_HIT.

Referenced by handle_delayed(), and handle_immediate().

◆ AddComboPointGain()

void Spell::AddComboPointGain ( Unit target,
int8  amount 
)
inline
533 {
534 if (target != m_comboTarget)
535 {
536 m_comboTarget = target;
537 m_comboPointGain = amount;
538 }
539 else
540 {
541 m_comboPointGain += amount;
542 }
543 }

References m_comboPointGain, and m_comboTarget.

Referenced by EffectAddComboPoints(), and EffectWeaponDmg().

◆ AddDestTarget()

void Spell::AddDestTarget ( SpellDestination const &  dest,
uint32  effIndex 
)
protected
2605{
2606 m_destTargets[effIndex] = dest;
2607}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2514{
2515 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2516 {
2517 if (!m_spellInfo->Effects[effIndex].IsEffect())
2518 effectMask &= ~(1 << effIndex);
2519 else
2520 {
2521 switch (m_spellInfo->Effects[effIndex].Effect)
2522 {
2526 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2527 effectMask &= ~(1 << effIndex);
2528 break;
2529 default:
2530 break;
2531 }
2532 }
2533 }
2534
2535 if (!effectMask)
2536 return;
2537
2538 ObjectGuid targetGUID = go->GetGUID();
2539
2540 // Lookup target in already in list
2541 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2542 {
2543 if (targetGUID == ihit->targetGUID) // Found in list
2544 {
2545 ihit->effectMask |= effectMask; // Add only effect mask
2546 return;
2547 }
2548 }
2549
2550 // This is new target calculate data for him
2551
2552 GOTargetInfo target;
2553 target.targetGUID = targetGUID;
2554 target.effectMask = effectMask;
2555 target.processed = false; // Effects not apply on target
2556
2557 // Spell have speed - need calculate incoming time
2558 if (m_spellInfo->Speed > 0.0f)
2559 {
2560 // calculate spell incoming interval
2561 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2562 if (dist < 5.0f)
2563 dist = 5.0f;
2564 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2565 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2566 m_delayMoment = target.timeDelay;
2567 }
2568 else
2569 target.timeDelay = 0LL;
2570
2571 // Add target to list
2572 m_UniqueGOTargetInfo.push_back(target);
2573}
std::uint64_t uint64
Definition: Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition: SharedDefines.h:1593
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition: SharedDefines.h:866
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition: SharedDefines.h:867
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition: SharedDefines.h:865
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1245
Definition: ObjectGuid.h:118
uint64 m_delayMoment
Definition: Spell.h:641
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:694

References Spell::GOTargetInfo::effectMask, SpellInfo::Effects, GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING, WorldObject::GetDistance(), GameObject::GetGoType(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, MAX_SPELL_EFFECTS, Spell::GOTargetInfo::processed, SpellInfo::Speed, SPELL_EFFECT_GAMEOBJECT_DAMAGE, SPELL_EFFECT_GAMEOBJECT_REPAIR, SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ AddItemTarget()

void Spell::AddItemTarget ( Item item,
uint32  effectMask 
)
protected
2576{
2577 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2578 if (!m_spellInfo->Effects[effIndex].IsEffect())
2579 effectMask &= ~(1 << effIndex);
2580
2581 // no effects left
2582 if (!effectMask)
2583 return;
2584
2585 // Lookup target in already in list
2586 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2587 {
2588 if (item == ihit->item) // Found in list
2589 {
2590 ihit->effectMask |= effectMask; // Add only effect mask
2591 return;
2592 }
2593 }
2594
2595 // This is new target add data
2596
2597 ItemTargetInfo target;
2598 target.item = item;
2599 target.effectMask = effectMask;
2600
2601 m_UniqueItemInfo.push_back(target);
2602}

References Spell::ItemTargetInfo::effectMask, SpellInfo::Effects, Spell::ItemTargetInfo::item, m_spellInfo, m_UniqueItemInfo, and MAX_SPELL_EFFECTS.

Referenced by SelectEffectTypeImplicitTargets(), and SelectImplicitTargetObjectTargets().

◆ AddUnitTarget()

void Spell::AddUnitTarget ( Unit target,
uint32  effectMask,
bool  checkIfValid = true,
bool  implicit = true 
)
protected
Todo:
: this is a hack
Todo:
: seduction should be casted only on humanoids (not demons)
2381{
2382 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2383 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2384 effectMask &= ~(1 << effIndex);
2385
2386 // no effects left
2387 if (!effectMask)
2388 return;
2389
2390 if (checkIfValid)
2391 {
2392 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2393 if (res != SPELL_CAST_OK)
2394 return;
2395 }
2396
2397 // Check for effect immune skip if immuned
2398 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2399 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
2400 effectMask &= ~(1 << effIndex);
2401
2402 ObjectGuid targetGUID = target->GetGUID();
2403
2404 // Lookup target in already in list
2405 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2406 {
2407 if (targetGUID == ihit->targetGUID) // Found in list
2408 {
2409 ihit->effectMask |= effectMask; // Immune effects removed from mask
2410 ihit->scaleAura = false;
2411 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2412 {
2413 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2414 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2415 ihit->scaleAura = true;
2416 }
2417
2418 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2419 return;
2420 }
2421 }
2422
2423 // This is new target calculate data for him
2424
2425 // Get spell hit result on target
2426 TargetInfo targetInfo;
2427 targetInfo.targetGUID = targetGUID; // Store target GUID
2428 targetInfo.effectMask = effectMask; // Store all effects not immune
2429 targetInfo.processed = false; // Effects not apply on target
2430 targetInfo.alive = target->IsAlive();
2431 targetInfo.damage = 0;
2432 targetInfo.crit = false;
2433 targetInfo.scaleAura = false;
2434 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2435 {
2436 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2437 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2438 targetInfo.scaleAura = true;
2439 }
2440
2441 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2442
2443 // Calculate hit result
2444 if (m_originalCaster)
2445 {
2446 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2447 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2448 {
2449 targetInfo.missCondition = SPELL_MISS_NONE;
2450 }
2451 }
2452 else
2453 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2454
2455 // Spell have speed - need calculate incoming time
2456 // Incoming time is zero for self casts. At least I think so.
2457 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2458 {
2459 // calculate spell incoming interval
2461 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2462
2463 if (dist < 5.0f)
2464 dist = 5.0f;
2465 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2466
2467 // Calculate minimum incoming time
2468 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2469 m_delayMoment = targetInfo.timeDelay;
2470 }
2471 else
2472 targetInfo.timeDelay = 0LL;
2473
2474 // If target reflect spell back to caster
2475 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2476 {
2477 // Calculate reflected spell result on caster
2479
2480 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2481 targetInfo.reflectResult = SPELL_MISS_PARRY;
2482
2483 // Increase time interval for reflected spells by 1.5
2485 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2486
2488
2489 // HACK: workaround check for succubus seduction case
2491 if (m_caster->IsPet())
2492 {
2493 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2494 switch (ci->family)
2495 {
2497 {
2498 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2499 cancel();
2500 }
2501 break;
2502 return;
2503 }
2504 }
2505 }
2506 else
2507 targetInfo.reflectResult = SPELL_MISS_NONE;
2508
2509 // Add target to list
2510 m_UniqueTargetInfo.push_back(targetInfo);
2511}
@ CREATURE_FAMILY_SUCCUBUS
Definition: SharedDefines.h:2664
@ SPELL_MISS_PARRY
Definition: SharedDefines.h:1523
@ SPELL_MISS_IMMUNE
Definition: SharedDefines.h:1526
@ SPELL_MISS_EVADE
Definition: SharedDefines.h:1525
@ SPELL_MISS_REFLECT
Definition: SharedDefines.h:1530
#define sObjectMgr
Definition: ObjectMgr.h:1634
@ SPELL_FLAG_REFLECTED
Definition: Spell.h:84
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
Definition: EventProcessor.h:103
uint64 CalculateTime(uint64 t_offset) const
Definition: EventProcessor.cpp:159
Definition: CreatureData.h:186
uint32 family
Definition: CreatureData.h:217
float GetPositionZ() const
Definition: Position.h:118
float GetPositionX() const
Definition: Position.h:116
float GetPositionY() const
Definition: Position.h:117
bool IsAlive() const
Definition: Unit.h:1658
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition: Unit.cpp:3470
EventProcessor m_Events
Definition: Unit.h:1910
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition: Unit.cpp:13001
uint8 GetLevel() const
Definition: Unit.h:1024
Definition: Spell.h:256
bool processed
Definition: Spell.h:262
int32 damage
Definition: Spell.h:266
SpellMissInfo missCondition
Definition: Spell.h:259
bool scaleAura
Definition: Spell.h:265
bool crit
Definition: Spell.h:264
uint64 timeDelay
Definition: Spell.h:258
ObjectGuid targetGUID
Definition: Spell.h:257
SpellMissInfo reflectResult
Definition: Spell.h:260
bool alive
Definition: Spell.h:263
uint8 effectMask
Definition: Spell.h:261
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition: Spell.cpp:7924
Definition: Spell.h:848
Definition: SpellInfo.h:316
uint32 SpellLevel
Definition: SpellInfo.h:360
SpellInfo const * GetFirstRankSpell() const
Definition: SpellInfo.cpp:2501
uint32 SpellIconID
Definition: SpellInfo.h:380
SpellCastResult CheckTarget(Unit const *caster, WorldObject const *target, bool implicit=true) const
Definition: SpellInfo.cpp:1759

References EventProcessor::AddEvent(), TargetInfo::alive, EventProcessor::CalculateTime(), cancel(), CheckEffectTarget(), SpellInfo::CheckTarget(), CREATURE_FAMILY_SUCCUBUS, TargetInfo::crit, TargetInfo::damage, TargetInfo::effectMask, SpellInfo::Effects, CreatureTemplate::family, WorldObject::GetDistance(), Object::GetEntry(), SpellInfo::GetFirstRankSpell(), Object::GetGUID(), Unit::GetLevel(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Unit::IsImmunedToSpellEffect(), Unit::IsPet(), m_auraScaleMask, m_canReflect, m_caster, m_delayMoment, Unit::m_Events, m_originalCaster, m_skipCheck, m_spellFlags, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, and TargetInfo::timeDelay.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
896{
897 if (m_targets.HasDst())
898 {
899 if (m_targets.HasTraj())
900 {
901 float speed = m_targets.GetSpeedXY();
902 if (speed > 0.0f)
903 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
904 }
905 else if (m_spellInfo->Speed > 0.0f)
906 {
907 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
908 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
909 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
910 }
911 }
912
913 return 0;
914}
float GetExactDist(float x, float y, float z) const
Definition: Position.h:177
bool HasTraj() const
Definition: Spell.h:168
bool HasDst() const
Definition: Spell.h:167
float GetSpeedXY() const
Definition: Spell.h:176
float GetDist2d() const
Definition: Spell.h:175
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:401

References SpellCastTargets::GetDist2d(), SpellCastTargets::GetDstPos(), Position::GetExactDist(), SpellCastTargets::GetSpeedXY(), SpellCastTargets::HasDst(), SpellCastTargets::HasTraj(), m_caster, m_spellInfo, m_targets, and SpellInfo::Speed.

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1154{
1156 if (Creature* creature = m_caster->ToCreature())
1157 runSpeed *= creature->GetCreatureTemplate()->speed_run;
1158
1159 float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
1160 if (multiplier <= 0.0f)
1161 multiplier = 1.0f;
1162
1163 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, m_caster->GetSpeed(MOVE_RUN) * 4.0f));
1164
1165 float duration = dist / speedXY;
1166 float durationSqr = duration * duration;
1167 float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
1168 float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
1169 float height;
1170 if (durationSqr < minHeight * 8 / Movement::gravity)
1171 height = minHeight;
1172 else if (durationSqr > maxHeight * 8 / Movement::gravity)
1173 height = maxHeight;
1174 else
1175 height = Movement::gravity * durationSqr / 8;
1176
1177 speedZ = std::sqrt(2 * Movement::gravity * height);
1178}
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition: Unit.cpp:73
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition: Unit.cpp:86
@ MOVE_RUN
Definition: UnitDefines.h:329
double gravity
Definition: MovementUtil.cpp:24
float GetSpeed(UnitMoveType mtype) const
Definition: Unit.cpp:14419

References baseMoveSpeed, SpellInfo::Effects, Unit::GetSpeed(), Movement::gravity, Unit::IsControlledByPlayer(), m_caster, m_spellInfo, MOVE_RUN, playerBaseMoveSpeed, and Object::ToCreature().

Referenced by EffectJump(), and EffectJumpDest().

◆ CalculateSpellDamage()

int32 Spell::CalculateSpellDamage ( uint8  i,
Unit const *  target 
) const
inline
int32 CalculateSpellDamage(Unit const *target, SpellInfo const *spellProto, uint8 effect_index, int32 const *basePoints=nullptr) const
Definition: Unit.cpp:14846
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: Spell.h:215

References Unit::CalculateSpellDamage(), SpellValue::EffectBasePoints, m_caster, m_spellInfo, and m_spellValue.

Referenced by CheckCast(), CheckEffectTarget(), EffectWeaponDmg(), and HandleEffects().

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8546{
8547 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8548 {
8549 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8550 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8551 for (; hookItr != hookItrEnd; ++hookItr)
8552 (*hookItr).Call(*scritr);
8553
8554 (*scritr)->_FinishScriptCall();
8555 }
8556}
@ SPELL_SCRIPT_HOOK_AFTER_CAST
Definition: SpellScript.h:172

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_CAST.

Referenced by _cast().

◆ CallScriptAfterHitHandlers()

void Spell::CallScriptAfterHitHandlers ( )
protected
8658{
8659 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8660 {
8661 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8662 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8663 for (; hookItr != hookItrEnd; ++hookItr)
8664 (*hookItr).Call(*scritr);
8665
8666 (*scritr)->_FinishScriptCall();
8667 }
8668}
@ SPELL_SCRIPT_HOOK_AFTER_HIT
Definition: SpellScript.h:165

References m_loadedScripts, and SPELL_SCRIPT_HOOK_AFTER_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptBeforeCastHandlers()

void Spell::CallScriptBeforeCastHandlers ( )
protected
8520{
8521 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8522 {
8523 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8524 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8525 for (; hookItr != hookItrEnd; ++hookItr)
8526 (*hookItr).Call(*scritr);
8527
8528 (*scritr)->_FinishScriptCall();
8529 }
8530}
@ SPELL_SCRIPT_HOOK_BEFORE_CAST
Definition: SpellScript.h:170

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_CAST.

Referenced by _cast().

◆ CallScriptBeforeHitHandlers()

void Spell::CallScriptBeforeHitHandlers ( SpellMissInfo  missInfo)
protected
8632{
8633 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8634 {
8635 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8636 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8637 for (; hookItr != hookItrEnd; ++hookItr)
8638 (*hookItr).Call(*scritr, missInfo);
8639
8640 (*scritr)->_FinishScriptCall();
8641 }
8642}
@ SPELL_SCRIPT_HOOK_BEFORE_HIT
Definition: SpellScript.h:163

References m_loadedScripts, and SPELL_SCRIPT_HOOK_BEFORE_HIT.

Referenced by DoAllEffectOnTarget().

◆ CallScriptCheckCastHandlers()

SpellCastResult Spell::CallScriptCheckCastHandlers ( )
protected
8559{
8561 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8562 {
8563 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8564 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8565 for (; hookItr != hookItrEnd; ++hookItr)
8566 {
8567 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8568 if (retVal == SPELL_CAST_OK)
8569 retVal = tempResult;
8570 }
8571
8572 (*scritr)->_FinishScriptCall();
8573 }
8574 return retVal;
8575}
@ SPELL_SCRIPT_HOOK_CHECK_CAST
Definition: SpellScript.h:169

References m_loadedScripts, SPELL_CAST_OK, and SPELL_SCRIPT_HOOK_CHECK_CAST.

Referenced by CheckCast().

◆ CallScriptDestinationTargetSelectHandlers()

void Spell::CallScriptDestinationTargetSelectHandlers ( SpellDestination target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8699{
8700 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8701 {
8702 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8703 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8704 for (; hookItr != hookItrEnd; ++hookItr)
8705 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8706 hookItr->Call(*scritr, target);
8707
8708 (*scritr)->_FinishScriptCall();
8709 }
8710}
@ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT
Definition: SpellScript.h:168

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT.

Referenced by SelectImplicitCasterDestTargets(), SelectImplicitDestDestTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8584{
8585 // execute script effect handler hooks and check if effects was prevented
8586 bool preventDefault = false;
8587 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8588 {
8589 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8590 SpellScriptHookType hookType;
8591 switch (mode)
8592 {
8594 effItr = (*scritr)->OnEffectLaunch.begin();
8595 effEndItr = (*scritr)->OnEffectLaunch.end();
8597 break;
8599 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8600 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8602 break;
8604 effItr = (*scritr)->OnEffectHit.begin();
8605 effEndItr = (*scritr)->OnEffectHit.end();
8607 break;
8609 effItr = (*scritr)->OnEffectHitTarget.begin();
8610 effEndItr = (*scritr)->OnEffectHitTarget.end();
8612 break;
8613 default:
8614 ABORT();
8615 return false;
8616 }
8617 (*scritr)->_PrepareScriptCall(hookType);
8618 for (; effItr != effEndItr; ++effItr)
8619 // effect execution can be prevented
8620 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8621 (*effItr).Call(*scritr, effIndex);
8622
8623 if (!preventDefault)
8624 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8625
8626 (*scritr)->_FinishScriptCall();
8627 }
8628 return preventDefault;
8629}
#define ABORT
Definition: Errors.h:76
@ SPELL_EFFECT_HANDLE_LAUNCH_TARGET
Definition: Spell.h:236
@ SPELL_EFFECT_HANDLE_HIT_TARGET
Definition: Spell.h:238
SpellScriptHookType
Definition: SpellScript.h:158
@ SPELL_SCRIPT_HOOK_EFFECT_HIT
Definition: SpellScript.h:161
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH
Definition: SpellScript.h:159
@ SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET
Definition: SpellScript.h:160
@ SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET
Definition: SpellScript.h:162

References ABORT, m_loadedScripts, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCRIPT_HOOK_EFFECT_HIT, SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_EFFECT_LAUNCH, and SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET.

Referenced by HandleEffects().

◆ CallScriptObjectAreaTargetSelectHandlers()

void Spell::CallScriptObjectAreaTargetSelectHandlers ( std::list< WorldObject * > &  targets,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8671{
8672 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8673 {
8674 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8675 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8676 for (; hookItr != hookItrEnd; ++hookItr)
8677 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8678 hookItr->Call(*scritr, targets);
8679
8680 (*scritr)->_FinishScriptCall();
8681 }
8682}
@ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT
Definition: SpellScript.h:166

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT.

Referenced by SelectImplicitAreaTargets(), SelectImplicitChainTargets(), and SelectImplicitConeTargets().

◆ CallScriptObjectTargetSelectHandlers()

void Spell::CallScriptObjectTargetSelectHandlers ( WorldObject *&  target,
SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
protected
8685{
8686 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8687 {
8688 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8689 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8690 for (; hookItr != hookItrEnd; ++hookItr)
8691 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8692 hookItr->Call(*scritr, target);
8693
8694 (*scritr)->_FinishScriptCall();
8695 }
8696}
@ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT
Definition: SpellScript.h:167

References SpellImplicitTargetInfo::GetTarget(), m_loadedScripts, m_spellInfo, and SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT.

Referenced by SelectEffectTypeImplicitTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ CallScriptOnCastHandlers()

void Spell::CallScriptOnCastHandlers ( )
protected
8533{
8534 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8535 {
8536 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8537 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8538 for (; hookItr != hookItrEnd; ++hookItr)
8539 (*hookItr).Call(*scritr);
8540
8541 (*scritr)->_FinishScriptCall();
8542 }
8543}
@ SPELL_SCRIPT_HOOK_ON_CAST
Definition: SpellScript.h:171

References m_loadedScripts, and SPELL_SCRIPT_HOOK_ON_CAST.

Referenced by _cast().

◆ CallScriptOnHitHandlers()

void Spell::CallScriptOnHitHandlers ( )
protected
8645{
8646 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8647 {
8648 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8649 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8650 for (; hookItr != hookItrEnd; ++hookItr)
8651 (*hookItr).Call(*scritr);
8652
8653 (*scritr)->_FinishScriptCall();
8654 }
8655}
@ SPELL_SCRIPT_HOOK_HIT
Definition: SpellScript.h:164

References m_loadedScripts, and SPELL_SCRIPT_HOOK_HIT.

Referenced by DoAllEffectOnTarget().

◆ CanAutoCast()

bool Spell::CanAutoCast ( Unit target)
7009{
7010 ObjectGuid targetguid = target->GetGUID();
7011
7012 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
7013 {
7015 {
7016 if (m_spellInfo->StackAmount <= 1)
7017 {
7018 if (target->HasAuraEffect(m_spellInfo->Id, j))
7019 return false;
7020 }
7021 else
7022 {
7023 if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
7024 if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
7025 return false;
7026 }
7027 }
7028 else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
7029 {
7030 if (target->HasAuraEffect(m_spellInfo->Id, j))
7031 return false;
7032 }
7033 }
7034
7035 SpellCastResult result = CheckPetCast(target);
7036
7037 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7038 {
7040 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7041 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7042 if (ihit->targetGUID == targetguid)
7043 return true;
7044 }
7045 return false; //target invalid
7046}
@ SPELL_EFFECT_APPLY_AURA
Definition: SharedDefines.h:784
@ SPELL_FAILED_UNIT_NOT_INFRONT
Definition: SharedDefines.h:1083
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition: Unit.cpp:5494
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition: Unit.cpp:5668
Definition: SpellAuraEffects.h:39
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6815
uint32 StackAmount
Definition: SpellInfo.h:371

References CheckPetCast(), SpellInfo::Effects, Unit::GetAuraEffect(), Object::GetGUID(), Unit::HasAuraEffect(), SpellInfo::Id, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectSpellTargets(), SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellInfo::StackAmount.

Referenced by PetAI::UpdateAI().

◆ cancel()

void Spell::cancel ( bool  bySelf = false)
3720{
3722 return;
3723
3724 uint32 oldState = m_spellState;
3726
3727 m_autoRepeat = false;
3728 switch (oldState)
3729 {
3733
3734 if (m_caster->IsPlayer())
3735 {
3737 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3738 }
3739 [[fallthrough]];
3742 break;
3744 if (!bySelf)
3745 {
3746 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3747 if ((*ihit).missCondition == SPELL_MISS_NONE)
3748 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3749 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3750
3753
3756 }
3757
3759 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3760
3761 // spell is canceled-take mods and clear list
3762 if (Player* player = m_caster->GetSpellModOwner())
3763 player->RemoveSpellMods(this);
3764
3765 m_appliedMods.clear();
3766 break;
3767 default:
3768 break;
3769 }
3770
3772 if (m_selfContainer && *m_selfContainer == this)
3773 *m_selfContainer = nullptr;
3774
3775 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3777 {
3779 }
3780
3781 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3783
3784 //set state back so finish will be processed
3785 m_spellState = oldState;
3786
3787 finish(false);
3788}
@ SPELL_EFFECT_ADD_FARSIGHT
Definition: SharedDefines.h:850
@ SPELL_FAILED_INTERRUPTED
Definition: SharedDefines.h:989
@ SPELL_STATE_PREPARING
Definition: Spell.h:226
@ SPELL_STATE_CASTING
Definition: Spell.h:227
@ AURA_REMOVE_BY_CANCEL
Definition: SpellAuraDefines.h:393
void SendCommand_Spell(T *o, ObjectGuid targetGUID, const char *prefix, uint32 id, int32 casttime)
Definition: ArenaSpectator.h:80
Map * FindMap() const
Definition: Object.h:532
bool NeedSendSpectatorData() const
Definition: Player.cpp:15407
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:6197
bool RemoveDynObject(uint32 spellId)
Definition: Unit.cpp:6141
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:5192
void CancelGlobalCooldown()
Definition: Spell.cpp:8886
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:561
UsedSpellMods m_appliedMods
Definition: Spell.h:547

References AURA_REMOVE_BY_CANCEL, CancelGlobalCooldown(), WorldObject::FindMap(), finish(), Object::GetGUID(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasEffect(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsPlayer(), m_appliedMods, m_autoRepeat, m_caster, m_originalCasterGUID, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Player::NeedSendSpectatorData(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), ArenaSpectator::SendCommand_Spell(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_EFFECT_ADD_FARSIGHT, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, and Object::ToPlayer().

Referenced by _cast(), SpellEvent::Abort(), AddUnitTarget(), SpellScript::Cancel(), Unit::InterruptSpell(), update(), and SpellEvent::~SpellEvent().

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
8887{
8889 return;
8890
8891 // Cancel global cooldown when interrupting current cast
8893 return;
8894
8895 // Only players or controlled units have global cooldown
8896 if (m_caster->GetCharmInfo())
8898 else if (m_caster->IsPlayer())
8900}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:538
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: Player.h:1788
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition: CharmInfo.cpp:408
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition: CharmInfo.h:159
CharmInfo * GetCharmInfo()
Definition: Unit.h:1206
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1449
uint32 StartRecoveryTime
Definition: SpellInfo.h:351

References GlobalCooldownMgr::CancelGlobalCooldown(), CURRENT_GENERIC_SPELL, Unit::GetCharmInfo(), Unit::GetCurrentSpell(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), Object::IsPlayer(), m_caster, m_spellInfo, SpellInfo::StartRecoveryTime, and Object::ToPlayer().

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
8736{
8737 // Relentless strikes, proc only from first effect
8738 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8739 return effMask & (1 << EFFECT_0);
8740
8741 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8742 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8743 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8744 {
8745 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8746 return true;
8747 }
8748 return effMask;
8749}
@ EFFECT_0
Definition: SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition: SharedDefines.h:1410
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition: SharedDefines.h:531

References EFFECT_0, SpellInfo::Effects, SpellInfo::HasAttribute(), m_spellInfo, MAX_SPELL_EFFECTS, SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET, SpellInfo::SpellIconID, and TARGET_UNIT_CASTER.

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8360{
8361 if (!lockId) // possible case for GO and maybe for items.
8362 return SPELL_CAST_OK;
8363
8364 // Get LockInfo
8365 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8366
8367 if (!lockInfo)
8369
8370 bool reqKey = false; // some locks not have reqs
8371
8372 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8373 {
8374 switch (lockInfo->Type[j])
8375 {
8376 // check key item (many fit cases can be)
8377 case LOCK_KEY_ITEM:
8378 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8379 return SPELL_CAST_OK;
8380 reqKey = true;
8381 break;
8382 // check key skill (only single first fit case can be)
8383 case LOCK_KEY_SKILL:
8384 {
8385 reqKey = true;
8386
8387 // wrong locktype, skip
8388 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8389 continue;
8390
8391 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8392
8393 if (skillId != SKILL_NONE)
8394 {
8395 reqSkillValue = lockInfo->Skill[j];
8396
8397 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8398 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8399 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8400
8401 // skill bonus provided by casting spell (mostly item spells)
8402 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8403 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8405 {
8406 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8407 }
8408
8409 if (skillValue < reqSkillValue)
8411 }
8412
8413 return SPELL_CAST_OK;
8414 }
8415 case LOCK_KEY_SPELL:
8416 {
8417 if (m_spellInfo->Id == lockInfo->Index[j])
8418 {
8419 return SPELL_CAST_OK;
8420 }
8421 reqKey = true;
8422 break;
8423 }
8424 }
8425 }
8426
8427 if (reqKey)
8429
8430 return SPELL_CAST_OK;
8431}
#define MAX_LOCK_CASE
Definition: DBCStructure.h:1304
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition: SharedDefines.h:1430
LockType
Definition: SharedDefines.h:2591
@ LOCK_KEY_ITEM
Definition: SharedDefines.h:2585
@ LOCK_KEY_SKILL
Definition: SharedDefines.h:2586
@ LOCK_KEY_SPELL
Definition: SharedDefines.h:2587
@ SPELL_FAILED_BAD_TARGETS
Definition: SharedDefines.h:961
@ SPELL_FAILED_LOW_CASTLEVEL
Definition: SharedDefines.h:998
SkillType SkillByLockType(LockType locktype)
Definition: SharedDefines.h:3020
@ SKILL_NONE
Definition: SharedDefines.h:2864
@ SKILL_LOCKPICKING
Definition: SharedDefines.h:2975
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5445
bool IsAbilityOfSkillType(uint32 skillType) const
Definition: SpellInfo.cpp:1005
Definition: DBCStructure.h:1307
uint32 Type[MAX_LOCK_CASE]
Definition: DBCStructure.h:1309
uint32 Index[MAX_LOCK_CASE]
Definition: DBCStructure.h:1310
uint32 Skill[MAX_LOCK_CASE]
Definition: DBCStructure.h:1311

References SpellInfo::Effects, Object::GetEntry(), Player::GetSkillValue(), SpellInfo::Id, LockEntry::Index, SpellInfo::IsAbilityOfSkillType(), Object::IsPlayer(), LOCK_KEY_ITEM, LOCK_KEY_SKILL, LOCK_KEY_SPELL, m_caster, m_CastItem, m_spellInfo, MAX_LOCK_CASE, LockEntry::Skill, SKILL_LOCKPICKING, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, TARGET_GAMEOBJECT_ITEM_TARGET, Object::ToPlayer(), and LockEntry::Type.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3791{
3792 Player* modOwner = m_caster->GetSpellModOwner();
3793 Spell* lastMod = nullptr;
3794 if (modOwner)
3795 {
3796 lastMod = modOwner->m_spellModTakingSpell;
3797 if (lastMod)
3798 modOwner->SetSpellModTakingSpell(lastMod, false);
3799 }
3800
3801 _cast(skipCheck);
3802
3803 if (lastMod)
3804 modOwner->SetSpellModTakingSpell(lastMod, true);
3805}
Spell * m_spellModTakingSpell
Definition: Player.h:2535
Definition: Spell.h:286
void _cast(bool skipCheck)
Definition: Spell.cpp:3807

References _cast(), Unit::GetSpellModOwner(), m_caster, Player::m_spellModTakingSpell, and Player::SetSpellModTakingSpell().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

◆ CheckCast()

SpellCastResult Spell::CheckCast ( bool  strict)
Todo:
: determine if there is some flag to enable/disable the check
5655{
5656 // check death state
5659
5660 // Spectator check
5661 if (m_caster->IsPlayer())
5662 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5663 return SPELL_FAILED_NOT_HERE;
5664
5666
5667 sScriptMgr->OnSpellCheckCast(this, strict, res);
5668
5669 if (res != SPELL_CAST_OK)
5670 return res;
5671
5672 // check cooldowns to prevent cheating
5674 {
5675 if (m_caster->IsPlayer())
5676 {
5677 //can cast triggered (by aura only?) spells while have this flag
5680
5682 {
5685 else
5687 }
5688
5689 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5692 }
5695 }
5696
5698 {
5701 }
5702
5703 // Check global cooldown
5706
5707 // only triggered spells can be processed an ended battleground
5708 if (!IsTriggered() && m_caster->IsPlayer())
5710 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5712
5713 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5714 {
5716 !m_caster->IsOutdoors())
5718
5722 }
5723
5724 // only check at first call, Stealth auras are already removed at second call
5725 // for now, ignore triggered spells
5727 {
5728 bool checkForm = true;
5729 // Ignore form req aura
5731 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5732 {
5733 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5734 continue;
5735 checkForm = false;
5736 break;
5737 }
5738 if (checkForm)
5739 {
5740 // Cannot be used in this stance/form
5742 if (shapeError != SPELL_CAST_OK)
5743 return shapeError;
5744
5747 }
5748 }
5749
5751 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5752 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5754
5755 bool reqCombat = true;
5757 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5758 {
5759 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5760 {
5761 m_needComboPoints = false;
5762 if ((*j)->GetMiscValue() == 1)
5763 {
5764 reqCombat = false;
5765 break;
5766 }
5767 }
5768 }
5769
5770 // caster state requirements
5771 // not for triggered spells (needed by execute)
5773 {
5778
5779 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5784
5785 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5787 }
5788
5789 // Xinef: exploit protection
5791 {
5792 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5793 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5794 if (instanceScript->IsEncounterInProgress())
5795 {
5796 if (Group* group = m_caster->ToPlayer()->GetGroup())
5797 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5798 if (Player* member = itr->GetSource())
5799 if (member->IsInMap(m_caster))
5800 if (Unit* victim = member->GetVictim())
5801 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5802 {
5803 m_caster->CombatStart(victim);
5804 victim->AddThreat(m_caster, 1.0f);
5805 break;
5806 }
5808 }
5809 }
5810
5811 // cancel autorepeat spells if cast start when moving
5812 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5813 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5814 {
5815 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5818 return SPELL_FAILED_MOVING;
5819 }
5820
5821 Vehicle* vehicle = m_caster->GetVehicle();
5823 {
5824 uint16 checkMask = 0;
5825 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5826 {
5827 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5829 {
5830 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5831 if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
5832 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5833 break;
5834 }
5835 }
5836
5839
5840 if (!checkMask)
5841 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5842
5843 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5844 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5846 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5848 }
5849
5850 // check spell cast conditions from database
5851 {
5854 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5855 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5856 {
5857 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5858 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5859 {
5863 }
5864 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5867 }
5868 }
5869
5870 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5871 // those spells may have incorrect target entries or not filled at all (for example 15332)
5872 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5873 // also, such casts shouldn't be sent to client
5874 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5876 {
5877 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5878 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5880 {
5882 if (castResult != SPELL_CAST_OK)
5883 return castResult;
5884 }
5885 }
5886
5887 if (Unit* target = m_targets.GetUnitTarget())
5888 {
5889 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5890 if (castResult != SPELL_CAST_OK)
5891 return castResult;
5892
5893 if (target != m_caster)
5894 {
5895 // Must be behind the target
5896 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5898
5899 // Target must be facing you
5900 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5902
5905 {
5906 bool castedByGameobject = false;
5907 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5909 {
5910 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5911 }
5912 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5913 {
5914 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5915 {
5916 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5917 }
5918 }
5919
5920 if (castedByGameobject)
5921 {
5922 // If spell casted by gameobject then ignore M2 models
5923 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5924 }
5925
5927 {
5929 }
5930 }
5931 }
5932 }
5933
5934 // Check for line of sight for spells with dest
5935 if (m_targets.HasDst())
5936 {
5937 float x, y, z;
5938 m_targets.GetDstPos()->GetPosition(x, y, z);
5939
5942 {
5943 bool castedByGameobject = false;
5944 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5946 {
5947 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5948 }
5949 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5950 {
5951 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5952 {
5953 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5954 }
5955 }
5956
5957 if (castedByGameobject)
5958 {
5959 // If spell casted by gameobject then ignore M2 models
5960 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5961 }
5962
5964 {
5966 }
5967 }
5968 }
5969
5970 // check pet presence
5971 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5972 {
5973 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5974 {
5976 {
5977 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5979 else
5980 return SPELL_FAILED_NO_PET;
5981 }
5982 break;
5983 }
5984 }
5985 // Spell casted only on battleground
5987 if (!m_caster->ToPlayer()->InBattleground())
5989
5990 // do not allow spells to be cast in arenas
5991 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5992 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
5995 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
5996 if (mapEntry->IsBattleArena())
5998
5999 // zone check
6001 {
6002 uint32 zone, area;
6003 m_caster->GetZoneAndAreaId(zone, area);
6004
6006 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
6007 if (locRes != SPELL_CAST_OK)
6008 return locRes;
6009 }
6010
6011 // not let players cast spells at mount (and let do it to creatures)
6014 {
6015 if (m_caster->IsInFlight())
6017 else
6019 }
6020
6021 SpellCastResult castResult = SPELL_CAST_OK;
6022
6023 // always (except passive spells) check items (focus object can be required for any type casts)
6024 if (!m_spellInfo->IsPassive())
6025 {
6026 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6027 castResult = CheckSpellFocus();
6028 if (castResult != SPELL_CAST_OK)
6029 return castResult;
6030
6031 castResult = CheckItems();
6032 if (castResult != SPELL_CAST_OK)
6033 return castResult;
6034 }
6035
6036 // Triggered spells also have range check
6038 castResult = CheckRange(strict);
6039 if (castResult != SPELL_CAST_OK)
6040 return castResult;
6041
6043 {
6044 castResult = CheckPower();
6045 if (castResult != SPELL_CAST_OK)
6046 return castResult;
6047 }
6048
6050 {
6051 return SPELL_CAST_OK;
6052 }
6053
6054 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6056 {
6058 if (castResult != SPELL_CAST_OK)
6059 return castResult;
6060
6061 // xinef: Enraged Regeneration: While this is active, the warrior is blocked from using abilities that trigger being enraged (which would do nothing and waste the cooldowns).
6063 {
6065 for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
6066 if (itr->type == m_spellInfo->Mechanic)
6068 }
6069 }
6070
6071 // script hook
6072 castResult = CallScriptCheckCastHandlers();
6073 if (castResult != SPELL_CAST_OK)
6074 return castResult;
6075
6076 bool hasDispellableAura = false;
6077 bool hasNonDispelEffect = false;
6078 uint32 dispelMask = 0;
6079 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6080 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6081 {
6083 {
6084 hasDispellableAura = true;
6085 break;
6086 }
6087
6088 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6089 }
6090 else if (m_spellInfo->Effects[i].IsEffect())
6091 {
6092 hasNonDispelEffect = true;
6093 break;
6094 }
6095
6096 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6097 {
6098 if (Unit* target = m_targets.GetUnitTarget())
6099 {
6100 // Xinef: do not allow to cast on hostile targets in sanctuary
6101 if (!m_caster->IsFriendlyTo(target))
6102 {
6103 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6104 {
6105 // Xinef: fix for duels
6106 Player* player = m_caster->ToPlayer();
6107 if (!player || !player->duel || target != player->duel->Opponent)
6109 }
6110 }
6111
6112 DispelChargesList dispelList;
6113 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6114
6115 if (dispelList.empty())
6117 }
6118 }
6119
6120 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6121 {
6122 // for effects of spells that have only one target
6123 switch (m_spellInfo->Effects[i].Effect)
6124 {
6126 {
6127 if (!m_caster->IsPlayer())
6129
6130 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6131 break;
6132
6133 Pet* pet = m_caster->ToPlayer()->GetPet();
6134
6135 if (!pet)
6136 return SPELL_FAILED_NO_PET;
6137
6138 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6139
6140 if (!learn_spellproto)
6142
6143 if (m_spellInfo->SpellLevel > pet->GetLevel())
6144 return SPELL_FAILED_LOWLEVEL;
6145
6146 break;
6147 }
6149 {
6150 // check target only for unit target case
6152 {
6153 if (!m_caster->IsPlayer())
6155
6156 Pet* pet = unitTarget->ToPet();
6157 if (!pet || pet->GetOwner() != m_caster)
6159
6160 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6161
6162 if (!learn_spellproto)
6164
6165 if (m_spellInfo->SpellLevel > pet->GetLevel())
6166 return SPELL_FAILED_LOWLEVEL;
6167 }
6168 break;
6169 }
6171 {
6172 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6173 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6174 if (m_caster->HasAura(gp->SpellId))
6176 break;
6177 }
6179 {
6180 if (!m_caster->IsPlayer())
6182
6183 Item* foodItem = m_targets.GetItemTarget();
6184 if (!foodItem)
6186
6187 Pet* pet = m_caster->ToPlayer()->GetPet();
6188
6189 if (!pet)
6190 return SPELL_FAILED_NO_PET;
6191
6192 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6194
6195 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6197
6198 if (m_caster->IsInCombat() || pet->IsInCombat())
6200
6201 break;
6202 }
6205 {
6206 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6207 if (m_caster->IsPlayer())
6208 if (Unit* target = m_targets.GetUnitTarget())
6209 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6211 break;
6212 }
6214 {
6216 {
6218 }
6219
6221 {
6222 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6223 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6225 }
6227 {
6228 // Exception for Master's Call
6229 if (m_spellInfo->Id != 54216)
6230 {
6231 return SPELL_FAILED_ROOTED;
6232 }
6233 }
6234 if (m_caster->IsPlayer())
6235 if (Unit* target = m_targets.GetUnitTarget())
6236 if (!target->IsAlive())
6238 // Xinef: Pass only explicit unit target spells
6239 // pussywizard:
6241 {
6242 Unit* target = m_targets.GetUnitTarget();
6243 if (!target)
6245
6246 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6247 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6249
6250 float objSize = target->GetCombatReach();
6251 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6252
6253 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6254 m_preGeneratedPath->SetPathLengthLimit(range);
6255
6256 // first try with raycast, if it fails fall back to normal path
6257 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6258 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6259 return SPELL_FAILED_NOPATH;
6260 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6261 return SPELL_FAILED_NOPATH;
6262 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6263 return SPELL_FAILED_NOPATH;
6264
6265 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6266 }
6267 if (Player* player = m_caster->ToPlayer())
6268 player->SetCanTeleport(true);
6269 break;
6270 }
6272 {
6275
6278
6279 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6280 if (!creature->IsCritter() && !creature->loot.isLooted())
6282
6283 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6284
6285 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6286 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6287 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6288 if (ReqValue > skillValue)
6290
6291 break;
6292 }
6294 {
6295 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6296 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6297 break;
6298
6299 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6300 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6301 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6303
6304 Item* pTempItem = nullptr;
6306 {
6307 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6308 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6309 }
6312
6313 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6314 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6316 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6318
6319 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6320 if (GameObject* go = m_targets.GetGOTarget())
6321 {
6322 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6323 {
6325 }
6326 }
6327 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6329 {
6330 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6331 {
6332 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6334 }
6335 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6338 }
6339
6340 // get the lock entry
6341 uint32 lockId = 0;
6342 if (GameObject* go = m_targets.GetGOTarget())
6343 {
6344 lockId = go->GetGOInfo()->GetLockId();
6345 if (!lockId)
6347 }
6348 else if (Item* itm = m_targets.GetItemTarget())
6349 lockId = itm->GetTemplate()->LockID;
6350
6351 SkillType skillId = SKILL_NONE;
6352 int32 reqSkillValue = 0;
6353 int32 skillValue = 0;
6354
6355 // check lock compatibility
6356 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6357 if (res != SPELL_CAST_OK)
6358 return res;
6359
6360 // chance for fail at lockpicking attempt
6361 // second check prevent fail at rechecks
6362 // herbalism and mining cannot fail as of patch 3.1.0
6363 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6364 {
6365 // chance for failure in orange lockpick
6366 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6367 {
6369 }
6370 }
6371 break;
6372 }
6374 {
6375 Unit* unitCaster = m_caster->ToUnit();
6376 if (!unitCaster)
6377 {
6379 }
6380
6381 Creature* pet = unitCaster->GetGuardianPet();
6382 if (pet)
6383 {
6384 if (pet->IsAlive())
6385 {
6387 }
6388 }
6389 else if (Player* playerCaster = m_caster->ToPlayer())
6390 {
6391 PetStable& petStable = playerCaster->GetOrInitPetStable();
6392 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6393 {
6394 return SPELL_FAILED_NO_PET;
6395 }
6396 }
6397
6398 break;
6399 }
6400 // This is generic summon effect
6402 {
6403 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6404 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6405 break;
6406 switch (SummonProperties->Category)
6407 {
6409 if (m_caster->GetPetGUID())
6411 [[fallthrough]];
6413 if (m_caster->GetCharmGUID())
6415 break;
6416 }
6417 break;
6418 }
6420 {
6422 {
6427 }
6428 break;
6429 }
6431 {
6432 Unit* unitCaster = m_caster->ToUnit();
6433 if (!unitCaster)
6435
6437 {
6438 if (m_caster->GetPetGUID())
6440 if (m_caster->GetCharmGUID())
6442 }
6443
6445 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6446 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6447
6448 Player* playerCaster = unitCaster->ToPlayer();
6449 if (playerCaster && playerCaster->GetPetStable())
6450 {
6451 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6452 if (info.first)
6453 {
6454 if (info.first->Type == HUNTER_PET)
6455 {
6456 if (!info.first->Health)
6457 {
6458 playerCaster->SendTameFailure(PET_TAME_DEAD);
6460 }
6461
6462 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6463 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6464 {
6465 // if problem in exotic pet
6466 if (creatureInfo && creatureInfo->IsTameable(true))
6468 else
6470
6472 }
6473 }
6474 }
6475 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6476 {
6479 }
6480 }
6481 break;
6482 }
6484 {
6485 if (!m_caster->IsPlayer())
6487 if (!m_caster->GetTarget())
6489
6491 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6493
6494 // Xinef: Implement summon pending error
6495 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6497
6498 // check if our map is dungeon
6499 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6500 if (map->IsDungeon())
6501 {
6502 uint32 mapId = m_caster->GetMap()->GetId();
6503 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6504 /*if (map->IsRaid())
6505 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6506 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6507 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6508
6509 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6510 if (!instance)
6512 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6514 }
6515 break;
6516 }
6517 // RETURN HERE
6519 {
6520 if (!m_caster->IsPlayer())
6522
6523 Player* playerCaster = m_caster->ToPlayer();
6524 //
6525 if (!(playerCaster->GetTarget()))
6527
6529
6530 if (!target ||
6531 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6533
6534 // Xinef: Implement summon pending error
6535 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6537
6538 break;
6539 }
6540 case SPELL_EFFECT_LEAP:
6542 {
6543 //Do not allow to cast it before BG starts.
6544 if (m_caster->IsPlayer())
6545 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6546 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6548 break;
6549 }
6551 {
6554
6555 bool found = false;
6557 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6558 {
6559 if (itr->second->GetBase()->IsPassive())
6560 continue;
6561
6562 if (!itr->second->IsPositive())
6563 continue;
6564
6565 found = true;
6566 break;
6567 }
6568
6569 if (!found)
6571
6572 break;
6573 }
6575 {
6577 {
6578 if (m_caster->IsPlayer())
6579 return SPELL_FAILED_ROOTED;
6580 else
6582 }
6583 break;
6584 }
6585 // xinef: do not allow to use leaps while rooted
6586 case SPELL_EFFECT_JUMP:
6588 {
6590 return SPELL_FAILED_ROOTED;
6591 break;
6592 }
6594 if (!sScriptMgr->CanSelectSpecTalent(this))
6596 // can't change during already started arena/battleground
6597 if (m_caster->IsPlayer())
6598 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6599 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6601 break;
6602 default:
6603 break;
6604 }
6605 }
6606
6607 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6608 {
6609 switch (m_spellInfo->Effects[i].ApplyAuraName)
6610 {
6611 case SPELL_AURA_DUMMY:
6612 break;
6614 {
6615 if (!m_caster->IsPlayer())
6616 return SPELL_FAILED_NO_PET;
6617
6618 Pet* pet = m_caster->ToPlayer()->GetPet();
6619 if (!pet)
6620 return SPELL_FAILED_NO_PET;
6621
6622 if (pet->GetCharmerGUID())
6623 return SPELL_FAILED_CHARMED;
6624 break;
6625 }
6629 {
6630 if (m_caster->GetCharmerGUID())
6631 return SPELL_FAILED_CHARMED;
6632
6633 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6635 {
6636 if (m_caster->GetPetGUID())
6638
6639 if (m_caster->GetCharmGUID())
6641 }
6642 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6643 {
6644 if (m_caster->GetCharmGUID())
6646 }
6647
6648 if (Unit* target = m_targets.GetUnitTarget())
6649 {
6650 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6652
6653 if (target->IsMounted())
6655
6656 if (target->GetCharmerGUID())
6657 return SPELL_FAILED_CHARMED;
6658
6659 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6661
6662 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6664
6665 int32 damage = CalculateSpellDamage(i, target);
6666 if (damage && int32(target->GetLevel()) > damage)
6668 }
6669
6670 break;
6671 }
6672 case SPELL_AURA_MOUNTED:
6673 {
6674 // Disallow casting flying mounts in water
6677
6678 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6679 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6680 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6681 if (it)
6682 allowMount = it->AllowMount;
6683 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6685
6688
6689 // xinef: dont allow to cast mounts in specific transforms
6690 if (m_caster->getTransForm())
6691 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6692 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6693 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6695
6696 break;
6697 }
6699 {
6700 if (!m_targets.GetUnitTarget())
6702
6703 // can be casted at non-friendly unit or own pet/charm
6706
6707 break;
6708 }
6709 case SPELL_AURA_FLY:
6711 {
6712 // Xinef: added water check
6713 if (m_caster->IsInWater())
6715
6716 // not allow cast fly spells if not have req. skills (all spells is self target)
6717 // allow always ghost flight spells
6719 {
6720 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6721 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6722 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6723 return SPELL_FAILED_NOT_HERE;
6724 }
6725 break;
6726 }
6728 {
6729 if (m_spellInfo->Effects[i].IsTargetingArea())
6730 break;
6731
6732 if (!m_caster->IsPlayer() || m_CastItem)
6733 break;
6734
6735 if (!m_targets.GetUnitTarget())
6737
6740
6741 break;
6742 }
6743 case SPELL_AURA_HOVER:
6744 {
6746 {
6748 }
6749 break;
6750 }
6752 {
6753 if (m_caster && m_caster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
6754 {
6756 }
6757 break;
6758 }
6759 default:
6760 break;
6761 }
6762 }
6763
6764 // check trade slot case (last, for allow catch any another cast problems)
6766 {
6767 if (m_CastItem)
6769
6770 if (!m_caster->IsPlayer())
6772
6773 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6774
6775 if (!my_trade)
6777
6779 if (slot != TRADE_SLOT_NONTRADED)
6781
6782 if (!IsTriggered())
6783 if (my_trade->GetSpell())
6785 }
6786
6787 // check if caster has at least 1 combo point on target for spells that require combo points
6789 {
6791 {
6793 {
6795 }
6796 }
6797 else
6798 {
6799 if (!m_caster->GetComboPoints())
6800 {
6802 }
6803 }
6804 }
6805
6806 // xinef: check relic cooldown
6810
6811 // all ok
6812 return SPELL_CAST_OK;
6813}
constexpr auto IN_MILLISECONDS
Definition: Common.h:53
constexpr auto MINUTE
Definition: Common.h:47
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
std::uint16_t uint16
Definition: Define.h:108
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition: DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition: DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:458
Difficulty
Definition: DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition: DBCEnums.h:262
@ GAMEOBJECT_TYPE_TRAP
Definition: SharedDefines.h:1566
@ GAMEOBJECT_TYPE_DOOR
Definition: SharedDefines.h:1560
Powers
Definition: SharedDefines.h:268
@ POWER_MANA
Definition: SharedDefines.h:269
@ SPELL_ATTR7_DEBUG_SPELL
Definition: SharedDefines.h:644
@ SPELL_EFFECT_LEAP
Definition: SharedDefines.h:807
@ SPELL_EFFECT_POWER_BURN
Definition: SharedDefines.h:840
@ SPELL_EFFECT_STUCK
Definition: SharedDefines.h:862
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition: SharedDefines.h:930
@ SPELL_EFFECT_APPLY_GLYPH
Definition: SharedDefines.h:852
@ SPELL_EFFECT_FEED_PET
Definition: SharedDefines.h:879
@ SPELL_EFFECT_SUMMON_PLAYER
Definition: SharedDefines.h:863
@ SPELL_EFFECT_JUMP_DEST
Definition: SharedDefines.h:820
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition: SharedDefines.h:821
@ SPELL_EFFECT_RESURRECT_PET
Definition: SharedDefines.h:887
@ SPELL_EFFECT_LEAP_BACK
Definition: SharedDefines.h:916
@ SPELL_EFFECT_SUMMON
Definition: SharedDefines.h:806
@ SPELL_EFFECT_POWER_DRAIN
Definition: SharedDefines.h:786
@ SPELL_EFFECT_RESURRECT
Definition: SharedDefines.h:796
@ SPELL_EFFECT_CHARGE
Definition: SharedDefines.h:874
@ SPELL_EFFECT_RESURRECT_NEW
Definition: SharedDefines.h:891
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition: SharedDefines.h:940
@ SPELL_EFFECT_LEARN_SPELL
Definition: SharedDefines.h:814
@ SPELL_EFFECT_JUMP
Definition: SharedDefines.h:819
@ SPELL_EFFECT_SKINNING
Definition: SharedDefines.h:873
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition: SharedDefines.h:931
@ SPELL_EFFECT_OPEN_LOCK
Definition: SharedDefines.h:811
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition: SharedDefines.h:904
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition: SharedDefines.h:835
@ SPELL_PREVENTION_TYPE_NONE
Definition: SharedDefines.h:1553
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition: SharedDefines.h:593
@ TARGET_UNIT_PET
Definition: SharedDefines.h:1414
@ TARGET_GAMEOBJECT_TARGET
Definition: SharedDefines.h:1427
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition: SharedDefines.h:458
@ SPELL_ATTR1_INITIATE_COMBAT
Definition: SharedDefines.h:428
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:504
@ PET_TAME_NOPET_AVAILABLE
Definition: SharedDefines.h:3683
@ PET_TAME_DEAD
Definition: SharedDefines.h:3686
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition: SharedDefines.h:3688
@ CLASS_WARLOCK
Definition: SharedDefines.h:149
@ IMMUNITY_MECHANIC
Definition: SharedDefines.h:1399
@ SPELLFAMILY_WARRIOR
Definition: SharedDefines.h:3532
SpellCustomErrors
Definition: SharedDefines.h:1142
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition: SharedDefines.h:1208
SpellAttr0
Definition: SharedDefines.h:381
@ SPELL_ATTR0_ONLY_INDOORS
Definition: SharedDefines.h:396
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition: SharedDefines.h:408
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition: SharedDefines.h:397
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition: SharedDefines.h:406
@ SPELL_ATTR0_PASSIVE
Definition: SharedDefines.h:388
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition: SharedDefines.h:405
@ SPELL_ATTR0_ONLY_STEALTHED
Definition: SharedDefines.h:399
AuraStateType
Definition: SharedDefines.h:1288
DispelType
Definition: SharedDefines.h:1371
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition: SharedDefines.h:1070
@ SPELL_FAILED_NOT_INFRONT
Definition: SharedDefines.h:1010
@ SPELL_FAILED_MOVING
Definition: SharedDefines.h:1000
@ SPELL_FAILED_NOT_MOUNTED
Definition: SharedDefines.h:1013
@ SPELL_FAILED_AFFECTING_COMBAT
Definition: SharedDefines.h:950
@ SPELL_FAILED_CASTER_AURASTATE
Definition: SharedDefines.h:971
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition: SharedDefines.h:1035
@ SPELL_FAILED_NOT_KNOWN
Definition: SharedDefines.h:1012
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition: SharedDefines.h:984
@ SPELL_FAILED_NOT_HERE
Definition: SharedDefines.h:1009
@ SPELL_FAILED_ROOTED
Definition: SharedDefines.h:1052
@ SPELL_FAILED_WRONG_PET_FOOD
Definition: SharedDefines.h:1084
@ SPELL_FAILED_CUSTOM_ERROR
Definition: SharedDefines.h:1121
@ SPELL_FAILED_SUMMON_PENDING
Definition: SharedDefines.h:1132
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition: SharedDefines.h:1095
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition: SharedDefines.h:960
@ SPELL_FAILED_TRY_AGAIN
Definition: SharedDefines.h:1081
@ SPELL_FAILED_NO_COMBO_POINTS
Definition: SharedDefines.h:1027
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition: SharedDefines.h:956
@ SPELL_FAILED_ALREADY_OPEN
Definition: SharedDefines.h:957
@ SPELL_FAILED_NOT_TRADING
Definition: SharedDefines.h:1020
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition: SharedDefines.h:1036
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition: SharedDefines.h:1032
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition: SharedDefines.h:1115
@ SPELL_FAILED_NOT_BEHIND
Definition: SharedDefines.h:1006
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition: SharedDefines.h:955
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition: SharedDefines.h:1086
@ SPELL_FAILED_HIGHLEVEL
Definition: SharedDefines.h:985
@ SPELL_FAILED_LOWLEVEL
Definition: SharedDefines.h:997
@ SPELL_FAILED_NOT_READY
Definition: SharedDefines.h:1016
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition: SharedDefines.h:1091
@ SPELL_FAILED_NOT_IN_ARENA
Definition: SharedDefines.h:1100
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition: SharedDefines.h:991
@ SPELL_FAILED_ONLY_STEALTHED
Definition: SharedDefines.h:1044
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition: SharedDefines.h:1067
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition: SharedDefines.h:1037
@ SPELL_FAILED_CANT_BE_CHARMED
Definition: SharedDefines.h:962
@ SPELL_FAILED_CASTER_DEAD
Definition: SharedDefines.h:972
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition: SharedDefines.h:1104
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition: SharedDefines.h:1131
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition: SharedDefines.h:1135
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition: SharedDefines.h:1075
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition: SharedDefines.h:1017
@ SPELL_FAILED_UNIQUE_GLYPH
Definition: SharedDefines.h:1125
@ SPELL_FAILED_ONLY_OUTDOORS
Definition: SharedDefines.h:1042
@ SPELL_FAILED_CHARMED
Definition: SharedDefines.h:973
@ SPELL_FAILED_LINE_OF_SIGHT
Definition: SharedDefines.h:996
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition: SharedDefines.h:1054
@ SPELL_FAILED_NO_PET
Definition: SharedDefines.h:1033
@ SPELL_FAILED_NOPATH
Definition: SharedDefines.h:1005
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition: SharedDefines.h:1056
@ SPELL_FAILED_ONLY_INDOORS
Definition: SharedDefines.h:1039
@ SPELL_FAILED_NOT_ON_TAXI
Definition: SharedDefines.h:1014
@ SPELL_FAILED_TARGET_FRIENDLY
Definition: SharedDefines.h:1064
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: SharedDefines.h:547
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition: SharedDefines.h:546
@ SUMMON_CATEGORY_PET
Definition: SharedDefines.h:3285
@ SUMMON_CATEGORY_PUPPET
Definition: SharedDefines.h:3286
SkillType
Definition: SharedDefines.h:2863
@ SKILL_MINING
Definition: SharedDefines.h:2919
@ SKILL_HERBALISM
Definition: SharedDefines.h:2915
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition: SharedDefines.h:616
#define sBattlefieldMgr
Definition: BattlefieldMgr.h:77
LineOfSightChecks
Definition: Map.h:189
@ LINEOFSIGHT_ALL_CHECKS
Definition: Map.h:196
@ TARGET_FLAG_UNIT_ENEMY
Definition: SpellInfo.h:53
@ TARGET_FLAG_ITEM
Definition: SpellInfo.h:50
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition: SpellInfo.h:192
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition: SpellInfo.h:193
@ SPELL_FLAG_REDIRECTED
Definition: Spell.h:85
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition: SpellDefines.h:61
@ AURA_INTERRUPT_FLAG_MOUNT
Definition: SpellDefines.h:60
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition: SpellDefines.h:132
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition: SpellDefines.h:142
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition: SpellDefines.h:143
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition: SpellDefines.h:141
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition: SpellDefines.h:131
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition: SpellDefines.h:150
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition: SpellDefines.h:144
std::vector< SpellImmune > SpellImmuneList
Definition: SpellDefines.h:179
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition: SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition: SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition: SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition: SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition: SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition: SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition: SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition: SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition: SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition: SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition: SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition: SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition: SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition: SpellAuraDefines.h:360
#define SPELL_RELIC_COOLDOWN
Definition: SpellMgr.h:34
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
@ PLAYER_ALLOW_ONLY_ABILITY
Definition: Player.h:497
@ INVTYPE_RELIC
Definition: ItemTemplate.h:284
@ GO_STATE_READY
Definition: GameObjectData.h:690
#define WORLD_TRIGGER
Definition: Unit.h:37
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition: Unit.h:77
@ MOVEMENTFLAG_FALLING_FAR
Definition: UnitDefines.h:357
@ CLASS_CONTEXT_PET
Definition: UnitDefines.h:215
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition: UnitDefines.h:285
@ UNIT_STATE_ROOT
Definition: UnitDefines.h:159
@ UNIT_STATE_CHARGING
Definition: UnitDefines.h:166
@ UNIT_FLAG_SKINNABLE
Definition: UnitDefines.h:255
@ HUNTER_PET
Definition: PetDefines.h:32
#define SPECTATOR_SPELL_BINDSIGHT
Definition: ArenaSpectator.h:38
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:203
@ STATUS_IN_PROGRESS
Definition: Battleground.h:202
#define sConditionMgr
Definition: ConditionMgr.h:290
@ CONDITION_SOURCE_TYPE_SPELL
Definition: ConditionMgr.h:140
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:237
@ PATHFIND_NOPATH
Definition: PathGenerator.h:50
@ PATHFIND_SHORT
Definition: PathGenerator.h:52
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:49
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:412
Player * FindPlayer(ObjectGuid const guid)
Definition: ObjectAccessor.cpp:245
Seconds GetGameTime()
Definition: GameTime.cpp:38
Definition: Battlefield.h:204
bool CanFlyIn()
Return if we can use mount in battlefield.
Definition: Battlefield.h:340
Definition: Battleground.h:303
Definition: ConditionMgr.h:182
Condition * mLastFailedCondition
Definition: ConditionMgr.h:184
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:183
uint32 ErrorType
Definition: ConditionMgr.h:205
uint8 ConditionTarget
Definition: ConditionMgr.h:209
uint32 ErrorTextId
Definition: ConditionMgr.h:206
Loot loot
Definition: Creature.h:226
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:205
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition: Creature.cpp:2826
SkillType GetRequiredLootSkill() const
Definition: CreatureData.h:257
bool IsTameable(bool exotic) const
Definition: CreatureData.h:274
Definition: TemporarySummon.h:40
Definition: GameObject.h:120
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:136
uint32 type
Definition: GameObjectData.h:33
bool IsLocked() const
Definition: Item.h:253
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:544
bool IsPotion() const
Definition: Item.h:337
uint32 ItemLevel
Definition: ItemTemplate.h:635
uint32 LockID
Definition: ItemTemplate.h:669
uint32 InventoryType
Definition: ItemTemplate.h:632
Unit * ToUnit()
Definition: Object.h:206
Map * GetMap() const
Definition: Object.h:531
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1192
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }, Optional< float > combatReach={ }) const
Definition: Object.cpp:1347
bool IsOutdoors() const
Definition: Object.cpp:3171
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition: Object.cpp:1326
float GetVisibilityRange() const
Definition: Object.cpp:1645
uint32 GetAreaId() const
Definition: Object.cpp:3154
uint32 GetZoneId() const
Definition: Object.cpp:3146
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3162
uint64 GetRawValue() const
Definition: ObjectGuid.h:142
bool IsPlayer() const
Definition: ObjectGuid.h:168
bool IsGameObject() const
Definition: ObjectGuid.h:171
void GetPosition(float &x, float &y) const
Definition: Position.h:121
uint32 GetMapId() const
Definition: Position.h:275
Player * GetOwner() const
Definition: Pet.cpp:2493
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1439
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition: Pet.cpp:1457
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, bool current)
Definition: Pet.cpp:170
Definition: PetDefines.h:202
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:225
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:228
void SetCanTeleport(bool value)
Definition: Player.h:2481
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1869
bool CanTameExoticPets() const
Definition: Player.h:2172
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition: Player.cpp:13229
bool InBattleground() const
Definition: Player.h:2235
PetStable * GetPetStable()
Definition: Player.h:1202
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:12203
WorldSession * GetSession() const
Definition: Player.h:1981
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16339
uint32 GetLastPotionId()
Definition: Player.h:1795
Group * GetGroup()
Definition: Player.h:2451
bool IsGameMaster() const
Definition: Player.h:1158
time_t GetSummonExpireTimer() const
Definition: Player.h:1101
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition: PlayerStorage.cpp:6705
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1108
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1861
Item * GetItemByGuid(ObjectGuid guid) const
Definition: PlayerStorage.cpp:407
uint32 GetSpell() const
Definition: TradeData.h:49
bool IsVehicle() const
Definition: Unit.h:757
Vehicle * GetVehicle() const
Definition: Unit.h:1740
Unit * GetOwner() const
Definition: Unit.cpp:10600
Pet * ToPet()
Definition: Unit.h:694
virtual bool HasSpellCooldown(uint32) const
Definition: Unit.h:1260
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1771
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition: Unit.h:1261
bool IsInDisallowedMountForm() const
Definition: Unit.cpp:21257
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:13624
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:718
bool IsInSanctuary() const
Definition: Unit.h:980
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition: Unit.h:801
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition: Unit.cpp:5809
float GetCombatReach() const override
Definition: Unit.h:828
UnitFlags GetUnitFlags() const
Definition: Unit.h:711
TempSummon * ToTempSummon()
Definition: Unit.h:696
bool HasStealthAura() const
Definition: Unit.h:1642
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5698
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition: Unit.h:652
bool IsInFlight() const
Definition: Unit.h:1574
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]
Definition: Unit.h:1912
void SendTameFailure(uint8 result)
Definition: Unit.cpp:19995
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:736
virtual bool IsInWater() const
Definition: Unit.cpp:4339
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:10547
bool isMoving() const
Definition: Unit.h:1577
ObjectGuid GetCharmGUID() const
Definition: Unit.h:686
VisibleAuraMap const * GetVisibleAuras()
Definition: Unit.h:1412
bool IsMounted() const
Definition: Unit.h:1702
Unit * GetVictim() const
Definition: Unit.h:853
bool IsCritter() const
Definition: Unit.h:790
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:678
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition: Unit.h:958
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:684
uint32 getTransForm() const
Definition: Unit.h:1785
virtual bool HasActivePowerType(Powers power)
Definition: Unit.h:1053
void RemoveMovementImpairingAuras(bool withRoot)
Definition: Unit.cpp:5234
bool IsTotem() const
Definition: Unit.h:756
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10651
ObjectGuid GetTarget() const
Definition: Unit.h:818
bool IsInCombat() const
Definition: Unit.h:884
ObjectGuid GetPetGUID() const
Definition: Unit.h:688
Definition: Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:597
Definition: Group.h:169
Definition: GroupReference.h:27
GroupReference * next()
Definition: GroupReference.h:36
Definition: InstanceScript.h:142
bool isLooted() const
Definition: LootMgr.h:367
Definition: Map.h:272
bool AllowMount
Definition: Map.h:275
bool IsDungeon() const
Definition: Map.h:446
bool IsBattlegroundOrArena() const
Definition: Map.h:454
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3322
uint32 GetId() const
Definition: Map.h:377
Difficulty GetDifficulty() const
Definition: Map.h:441
uint32 GetRecruiterId() const
Definition: WorldSession.h:526
uint32 GetAccountId() const
Definition: WorldSession.h:361
GameObject * GetGOTarget() const
Definition: Spell.cpp:264
ObjectGuid GetItemTargetGUID() const
Definition: Spell.h:140
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition: Spell.h:778
SpellCastResult CheckSpellFocus()
Definition: Spell.cpp:7747
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:8359
SpellCastResult CheckItems()
Definition: Spell.cpp:7179
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition: Spell.h:479
SpellCastResult CheckPower()
Definition: Spell.cpp:7134
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition: Spell.cpp:6851
SpellCastResult CallScriptCheckCastHandlers()
Definition: Spell.cpp:8558
bool IsTriggered() const
Definition: Spell.h:554
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:7048
bool HasGlobalCooldown() const
Definition: Spell.cpp:8830
Definition: SpellInfo.h:249
int32 MiscValue
Definition: SpellInfo.h:263
uint32 ApplyAuraName
Definition: SpellInfo.h:254
uint32 PreventionType
Definition: SpellInfo.h:390
uint32 CasterAuraSpell
Definition: SpellInfo.h:343
SpellCastResult CheckShapeshift(uint32 form) const
Definition: SpellInfo.cpp:1434
uint32 Mechanic
Definition: SpellInfo.h:323
uint32 GetDispelMask() const
Definition: SpellInfo.cpp:2041
uint32 GetRecoveryTime() const
Definition: SpellInfo.cpp:2396
bool IsSelfCast() const
Definition: SpellInfo.cpp:1090
uint32 CasterAuraState
Definition: SpellInfo.h:339
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1232
uint32 CasterAuraStateNot
Definition: SpellInfo.h:341
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition: SpellInfo.cpp:1489
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:1987
int32 AreaGroupId
Definition: SpellInfo.h:391
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2323
uint32 GetExplicitTargetMask() const
Definition: SpellInfo.cpp:2055
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1033
uint32 ExcludeCasterAuraSpell
Definition: SpellInfo.h:345
uint32 SpellFamilyName
Definition: SpellInfo.h:387
uint32 AuraInterruptFlags
Definition: SpellInfo.h:353
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition: SpellInfo.cpp:1937
Definition: DBCStructure.h:518
Definition: DBCStructure.h:1020
Definition: DBCStructure.h:1324
bool IsDungeon() const
Definition: DBCStructure.h:1350
Definition: DBCStructure.h:1816
uint32 flags1
Definition: DBCStructure.h:1821
Definition: DBCStructure.h:1908
uint32 Category
Definition: DBCStructure.h:1910
Definition: DBCStructure.h:2063
uint32 m_flags
Definition: DBCStructure.h:2065

References InstanceTemplate::AllowMount, SpellEffectInfo::ApplyAuraName, AREA_FLAG_NO_FLY_ZONE, SpellInfo::AreaGroupId, AURA_INTERRUPT_FLAG_MOUNT, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellInfo::AuraInterruptFlags, CalculateSpellDamage(), CallScriptCheckCastHandlers(), SpellInfo::CanBeUsedInCombat(), Battlefield::CanFlyIn(), CanOpenLock(), Player::CanTameExoticPets(), Player::CanUseBattlegroundObject(), SpellInfo::CasterAuraSpell, SpellInfo::CasterAuraState, SpellInfo::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), SpellInfo::CheckExplicitTarget(), CheckItems(), SpellInfo::CheckLocation(), CheckPower(), CheckRange(), SpellInfo::CheckShapeshift(), CheckSpellFocus(), SpellInfo::CheckTarget(), CLASS_CONTEXT_PET, CLASS_WARLOCK, Unit::CombatStart(), CONDITION_SOURCE_TYPE_SPELL, Condition::ConditionTarget, PetStable::CurrentPet, damage, Player::duel, EFFECT_0, SpellInfo::Effects, Condition::ErrorTextId, Condition::ErrorType, SpellInfo::ExcludeCasterAuraSpell, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), SpellShapeshiftFormEntry::flags1, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), WorldObject::GetAreaId(), Unit::GetAuraEffectsByType(), Player::GetBattleground(), Unit::GetCharm(), Unit::GetCharmerGUID(), Unit::GetCharmGUID(), Unit::GetCombatReach(), Unit::GetComboPoints(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), SpellInfo::GetDispelMask(), WorldObject::GetDistance(), SpellCastTargets::GetDstPos(), Object::GetEntry(), SpellInfo::GetExplicitTargetMask(), Map::GetGameObject(), GameTime::GetGameTime(), GameObject::GetGOInfo(), SpellCastTargets::GetGOTarget(), Player::GetGroup(), Unit::GetGuardianPet(), Map::GetId(), WorldObject::GetInstanceScript(), Player::GetItemByGuid(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetGUID(), Player::GetLastPotionId(), Unit::GetLevel(), Pet::GetLoadPetInfo(), WorldObject::GetMap(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectGuid::GetRawValue(), SpellInfo::GetRecoveryTime(), WorldSession::GetRecruiterId(), CreatureTemplate::GetRequiredLootSkill(), SpellInfo::GetSchoolMask(), Vehicle::GetSeatForPassenger(), Player::GetSession(), Unit::GetShapeshiftForm(), Player::GetSkillValue(), TradeData::GetSpell(), Player::GetSummonExpireTimer(), Unit::GetTarget(), SpellCastTargets::GetTargetMask(), Item::GetTemplate(), Player::GetTradeData(), Unit::getTransForm(), Unit::GetUnitFlags(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicle(), Unit::GetVictim(), WorldObject::GetVisibilityRange(), Unit::GetVisibleAuras(), WorldObject::GetZoneAndAreaId(), WorldObject::GetZoneId(), GO_STATE_READY, Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasGlobalCooldown(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::HasSpellCooldown(), Unit::HasSpellItemCooldown(), Unit::HasStealthAura(), HasTriggeredCastFlag(), Unit::HasUnitFlag2(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Pet::HaveInDiet(), HUNTER_PET, SpellInfo::Id, IMMUNITY_MECHANIC, IN_MILLISECONDS, Player::InBattleground(), ItemTemplate::InventoryType, INVTYPE_RELIC, irand(), Unit::IsAlive(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsClass(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsCritter(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Player::IsGameMaster(), ObjectGuid::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Player::IsInSameRaidWith(), Unit::IsInSanctuary(), Unit::IsInWater(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), IsNextMeleeSwingSpell(), WorldObject::IsOutdoors(), SpellInfo::IsPassive(), DisableMgr::IsPathfindingEnabled(), Object::IsPlayer(), SpellInfo::IsPositive(), Item::IsPotion(), Unit::IsScriptOverriden(), SpellInfo::IsSelfCast(), Creature::IsSpellProhibited(), CreatureTemplate::IsTameable(), Unit::IsTotem(), IsTriggered(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, LINEOFSIGHT_ALL_CHECKS, ItemTemplate::LockID, Creature::loot, VMAP::M2, m_caster, m_CastItem, m_customError, VehicleSeatEntry::m_flags, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_preGeneratedPath, m_selfContainer, m_spellFlags, Unit::m_spellImmune, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, SpellInfo::Mechanic, MINUTE, SpellEffectInfo::MiscValue, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLING_FAR, SpellInfo::NeedsExplicitUnitTarget(), GroupReference::next(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_SHORT, PET_TAME_CANT_CONTROL_EXOTIC, PET_TAME_DEAD, PET_TAME_NOPET_AVAILABLE, PLAYER_ALLOW_ONLY_ABILITY, POWER_MANA, SpellInfo::PreventionType, Unit::RemoveMovementImpairingAuras(), sAreaTableStore, Player::Satisfy(), sBattlefieldMgr, sConditionMgr, Unit::SendTameFailure(), sGlyphPropertiesStore, SKILL_HERBALISM, SKILL_LOCKPICKING, SKILL_MINING, SKILL_NONE, sMapStore, sObjectMgr, SPECTATOR_SPELL_BINDSIGHT, SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD, SPELL_ATTR0_ALLOW_WHILE_MOUNTED, SPELL_ATTR0_AURA_IS_DEBUFF, SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET, SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER, SPELL_ATTR0_NO_IMMUNITIES, SPELL_ATTR0_ONLY_INDOORS, SPELL_ATTR0_ONLY_OUTDOORS, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_DISMISS_PET_FIRST, SPELL_ATTR1_INITIATE_COMBAT, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_ATTR3_ONLY_BATTLEGROUNDS, SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS, SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND, SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT, SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE, SPELL_ATTR7_DEBUG_SPELL, SPELL_AURA_ABILITY_IGNORE_AURASTATE, SPELL_AURA_AOE_CHARM, SPELL_AURA_BLOCK_SPELL_FAMILY, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_HOVER, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_IGNORE_SHAPESHIFT, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_CAST_OK, SPELL_CUSTOM_ERROR_GM_ONLY, SPELL_EFFECT_APPLY_GLYPH, SPELL_EFFECT_CHARGE, SPELL_EFFECT_CREATE_TAMED_PET, SPELL_EFFECT_DISPEL, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_JUMP, SPELL_EFFECT_JUMP_DEST, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEAP_BACK, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_RESURRECT, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_RESURRECT_PET, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_EFFECT_TALENT_SPEC_SELECT, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_ALREADY_OPEN, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_CHARMED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_DAMAGE_IMMUNE, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_ALREADY_ENCHANTED, SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MOVING, SPELL_FAILED_NO_COMBO_POINTS, SPELL_FAILED_NO_MOUNTS_ALLOWED, SPELL_FAILED_NO_PET, SPELL_FAILED_NOPATH, SPELL_FAILED_NOT_BEHIND, SPELL_FAILED_NOT_HERE, SPELL_FAILED_NOT_IN_ARENA, SPELL_FAILED_NOT_IN_BATTLEGROUND, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_NOT_KNOWN, SPELL_FAILED_NOT_MOUNTED, SPELL_FAILED_NOT_ON_MOUNTED, SPELL_FAILED_NOT_ON_TAXI, SPELL_FAILED_NOT_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOT_TRADING, SPELL_FAILED_NOTHING_TO_DISPEL, SPELL_FAILED_NOTHING_TO_STEAL, SPELL_FAILED_ONLY_ABOVEWATER, SPELL_FAILED_ONLY_BATTLEGROUNDS, SPELL_FAILED_ONLY_INDOORS, SPELL_FAILED_ONLY_OUTDOORS, SPELL_FAILED_ONLY_STEALTHED, SPELL_FAILED_ROOTED, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_SUMMON_PENDING, SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNIQUE_GLYPH, SPELL_FAILED_WRONG_PET_FOOD, SPELL_FLAG_REDIRECTED, SPELL_PREVENTION_TYPE_NONE, SPELL_RELIC_COOLDOWN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyName, TriggeredByAuraSpellData::spellInfo, SpellInfo::SpellLevel, sScriptMgr, sSpellMgr, sSpellShapeshiftFormStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, TARGET_FLAG_ITEM, TARGET_FLAG_TRADE_ITEM, TARGET_FLAG_UNIT_ENEMY, TARGET_GAMEOBJECT_ITEM_TARGET, TARGET_GAMEOBJECT_TARGET, TARGET_UNIT_PET, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), Unit::ToTempSummon(), Object::ToUnit(), TRADE_SLOT_NONTRADED, TRIGGERED_IGNORE_CASTER_AURAS, TRIGGERED_IGNORE_CASTER_AURASTATE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE, TRIGGERED_IGNORE_EFFECTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, TRIGGERED_IGNORE_SHAPESHIFT, TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD, GameObjectTemplate::type, UNIT_FLAG2_ALLOW_CHEAT_SPELLS, UNIT_FLAG_SKINNABLE, UNIT_STATE_CHARGING, UNIT_STATE_ROOT, unitTarget, PetStable::UnslottedPets, VEHICLE_SEAT_FLAG_CAN_ATTACK, VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL, VEHICLE_SEAT_FLAG_UNCONTROLLED, and WORLD_TRIGGER.

Referenced by _cast(), Unit::_UpdateAutoRepeatSpell(), Unit::AttackerStateUpdate(), Player::CastItemUseSpell(), CheckPetCast(), WorldSession::HandleAcceptTradeOpcode(), prepare(), and go_wind_stone::go_wind_stoneAI::SummonNPC().

◆ CheckCasterAuras()

SpellCastResult Spell::CheckCasterAuras ( bool  preventionOnly) const
6852{
6853 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6855 return SPELL_CAST_OK;
6856
6857 uint8 school_immune = 0;
6858 uint32 mechanic_immune = 0;
6859 uint32 dispel_immune = 0;
6860
6861 // Check if the spell grants school or mechanic immunity.
6862 // We use bitmasks so the loop is done only once and not on every aura check below.
6864 {
6865 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6866 {
6867 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6868 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6869 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6870 mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
6871 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6872 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6873 }
6874 // immune movement impairment and loss of control
6875 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6876 if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 65547 || m_spellInfo->Id == 53490 || m_spellInfo->Id == 19574 || m_spellInfo->Id == 34471 || m_spellInfo->Id == 46227)
6878 }
6879
6881
6882 // Glyph of Pain Suppression
6883 // there is no other way to handle it
6884 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6885 usableInStun = false;
6886
6887 // Check whether the cast should be prevented by any state you might have.
6888 SpellCastResult prevented_reason = SPELL_CAST_OK;
6889 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6890 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6891
6892 // Xinef: if spell is triggered check preventionType only
6893 if (!preventionOnly)
6894 {
6895 if (unitflag & UNIT_FLAG_STUNNED)
6896 {
6897 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6898 if (usableInStun)
6899 {
6900 bool foundNotStun = false;
6901 uint32 mask = (1 << MECHANIC_STUN) | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_HORROR);
6902 // Barkskin should skip sleep effects, sap and fears
6903 if (m_spellInfo->Id == 22812)
6904 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6905 // Hand of Freedom, can be used while sapped
6906 if (m_spellInfo->Id == 1044)
6907 mask |= 1 << MECHANIC_SAPPED;
6909 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6910 {
6911 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6912 {
6913 foundNotStun = true;
6914 break;
6915 }
6916 }
6917 if (foundNotStun)
6918 prevented_reason = SPELL_FAILED_STUNNED;
6919 }
6920 else
6921 prevented_reason = SPELL_FAILED_STUNNED;
6922 }
6924 prevented_reason = SPELL_FAILED_CONFUSED;
6926 prevented_reason = SPELL_FAILED_FLEEING;
6927 }
6928
6929 // Xinef: if there is no prevented_reason, check prevention types
6930 if (prevented_reason == SPELL_CAST_OK)
6931 {
6933 prevented_reason = SPELL_FAILED_SILENCED;
6935 prevented_reason = SPELL_FAILED_PACIFIED;
6936 }
6937
6938 // Attr must make flag drop spell totally immune from all effects
6939 if (prevented_reason != SPELL_CAST_OK)
6940 {
6941 if (school_immune || mechanic_immune || dispel_immune)
6942 {
6943 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6945 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6946 {
6947 Aura const* aura = itr->second->GetBase();
6948 SpellInfo const* auraInfo = aura->GetSpellInfo();
6949 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6950 continue;
6951 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6952 continue;
6953 if (auraInfo->GetDispelMask() & dispel_immune)
6954 continue;
6955
6956 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6957 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6958 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6959 {
6960 if (AuraEffect* part = aura->GetEffect(i))
6961 {
6962 switch (part->GetAuraType())
6963 {
6965 {
6966 uint32 mask = 1 << MECHANIC_STUN;
6967 // Barkskin should skip sleep effects, sap and fears
6968 if (m_spellInfo->Id == 22812)
6969 mask |= 1 << MECHANIC_SAPPED | 1 << MECHANIC_HORROR | 1 << MECHANIC_SLEEP;
6970 // Hand of Freedom, can be used while sapped
6971 if (m_spellInfo->Id == 1044)
6972 mask |= 1 << MECHANIC_SAPPED;
6973
6974 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
6975 return SPELL_FAILED_STUNNED;
6976 break;
6977 }
6980 return SPELL_FAILED_CONFUSED;
6981 break;
6984 return SPELL_FAILED_FLEEING;
6985 break;
6990 return SPELL_FAILED_PACIFIED;
6992 return SPELL_FAILED_SILENCED;
6993 break;
6994 default:
6995 break;
6996 }
6997 }
6998 }
6999 }
7000 }
7001 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
7002 else
7003 return prevented_reason;
7004 }
7005 return SPELL_CAST_OK;
7006}
@ SPELL_PREVENTION_TYPE_SILENCE
Definition: SharedDefines.h:1554
@ SPELL_PREVENTION_TYPE_PACIFY
Definition: SharedDefines.h:1555
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition: SharedDefines.h:570
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition: SharedDefines.h:584
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition: SharedDefines.h:585
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition: SharedDefines.h:434
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition: SharedDefines.h:435
@ MECHANIC_STUN
Definition: SharedDefines.h:1337
@ MECHANIC_FREEZE
Definition: SharedDefines.h:1338
@ MECHANIC_SLEEP
Definition: SharedDefines.h:1335
@ MECHANIC_SAPPED
Definition: SharedDefines.h:1355
@ MECHANIC_HORROR
Definition: SharedDefines.h:1349
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition: SharedDefines.h:1361
@ SPELL_FAILED_STUNNED
Definition: SharedDefines.h:1057
@ SPELL_FAILED_CONFUSED
Definition: SharedDefines.h:975
@ SPELL_FAILED_SILENCED
Definition: SharedDefines.h:1053
@ SPELL_FAILED_FLEEING
Definition: SharedDefines.h:983
@ SPELL_FAILED_PACIFIED
Definition: SharedDefines.h:1047
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition: SharedDefines.h:606
@ SPELL_AURA_DISPEL_IMMUNITY
Definition: SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition: SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition: SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition: SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition: SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition: SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition: SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition: SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition: SpellAuraDefines.h:75
@ UNIT_FLAG_STUNNED
Definition: UnitDefines.h:247
@ UNIT_FLAG_PACIFIED
Definition: UnitDefines.h:246
@ UNIT_FLAG_CONFUSED
Definition: UnitDefines.h:251
@ UNIT_FLAG_FLEEING
Definition: UnitDefines.h:252
@ UNIT_FLAG_SILENCED
Definition: UnitDefines.h:242
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition: Unit.h:639
AuraApplicationMap & GetAppliedAuras()
Definition: Unit.h:1304
Definition: SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition: SpellAuras.h:175
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:100
uint32 GetAllEffectsMechanicMask() const
Definition: SpellInfo.cpp:1992

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

void Spell::CheckDst ( )
inline
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:406

References SpellCastTargets::HasDst(), m_caster, m_targets, and SpellCastTargets::SetDst().

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8492{
8493 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8495}
#define ASSERT
Definition: Errors.h:68

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by PrepareTargetProcessing(), and ~Spell().

◆ CheckEffectTarget()

bool Spell::CheckEffectTarget ( Unit const *  target,
uint32  eff 
) const
Todo:
: below shouldn't be here, but it's temporary
7925{
7926 switch (m_spellInfo->Effects[eff].ApplyAuraName)
7927 {
7932 if (target->IsCreature() && target->IsVehicle())
7933 return false;
7934 if (target->IsMounted())
7935 return false;
7936 if (target->GetCharmerGUID())
7937 return false;
7938 if (int32 damage = CalculateSpellDamage(eff, target))
7939 if ((int32)target->GetLevel() > damage)
7940 return false;
7941 break;
7942 default:
7943 break;
7944 }
7945
7946 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
7947 // this is only for target addition and target has to have unselectable flag, this is valid for FLAG_EXTRA_TRIGGER and quest triggers however there are some without this flag, used not_selectable
7948 if (m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) || (target->IsCreature() && target->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && (m_spellInfo->Effects[eff].TargetA.GetCheckType() == TARGET_CHECK_ENTRY || m_spellInfo->Effects[eff].TargetB.GetCheckType() == TARGET_CHECK_ENTRY)))
7949 return true;
7950
7951 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
7954 {
7955 return true;
7956 }
7957
7959 //Check targets for LOS visibility (except spells without range limitations)
7960 switch (m_spellInfo->Effects[eff].Effect)
7961 {
7963 // player far away, maybe his corpse near?
7964 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
7965 {
7967 return false;
7968
7970 if (!corpse)
7971 return false;
7972
7973 if (target->GetGUID() != corpse->GetOwnerGUID())
7974 return false;
7975
7977 return false;
7978 }
7979 break;
7981 {
7983 {
7984 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
7985 return true;
7986
7987 return false;
7988 }
7989
7991 if (!corpse)
7992 return false;
7993
7994 if (target->GetGUID() != corpse->GetOwnerGUID())
7995 return false;
7996
7998 return false;
7999
8001 return false;
8002 }
8003 break;
8005 if (!m_caster->IsPlayer() || !target->IsPlayer())
8006 return false;
8007 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8008 return false;
8009 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8010 return false;
8011 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8012 return false;
8013 break;
8014 default: // normal case
8015 {
8016 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8017 GameObject* gobCaster = nullptr;
8019 {
8021 }
8022 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8023 {
8024 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8025 {
8026 gobCaster = tempSummon->GetSummonerGameObject();
8027 }
8028 }
8029
8030 if (gobCaster)
8031 {
8032 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8033 {
8034 return true;
8035 }
8036
8037 // If spell casted by gameobject then ignore M2 models
8038 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8039 }
8040
8041 if (target != m_caster)
8042 {
8043 if (m_targets.HasDst())
8044 {
8045 float x = m_targets.GetDstPos()->GetPositionX();
8046 float y = m_targets.GetDstPos()->GetPositionY();
8047 float z = m_targets.GetDstPos()->GetPositionZ();
8048
8049 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8050 {
8051 return false;
8052 }
8053 }
8055 {
8056 return false;
8057 }
8058 }
8059 break;
8060 }
8061 }
8062
8063 return true;
8064}
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition: SharedDefines.h:894
@ TARGET_CHECK_ENTRY
Definition: SpellInfo.h:115
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:246
@ CORPSE_FLAG_LOOTABLE
Definition: Corpse.h:45
@ CORPSE_FIELD_FLAGS
Definition: UpdateFields.h:427
@ UNIT_FLAG_NOT_SELECTABLE
Definition: UnitDefines.h:254
@ SPELL_DISABLE_LOS
Definition: DisableMgr.h:48
@ DISABLE_TYPE_SPELL
Definition: DisableMgr.h:27
#define sWorld
Definition: World.h:443
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:307
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:179
Definition: Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition: Corpse.h:68
bool IsIgnoringLOSChecks() const
Definition: GameObjectData.h:642
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:889
bool IsARecruiter() const
Definition: WorldSession.h:527
ObjectGuid GetCorpseTargetGUID() const
Definition: Spell.cpp:281

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), Object::GetEntry(), Map::GetGameObject(), GameObject::GetGOInfo(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Corpse::GetOwnerGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldSession::GetRecruiterId(), Player::GetSession(), SpellInfo::HasAttribute(), SpellCastTargets::HasDst(), Object::HasFlag(), Unit::HasUnitFlag(), SpellInfo::Id, WorldSession::IsARecruiter(), Object::IsCreature(), DisableMgr::IsDisabledFor(), ObjectGuid::IsGameObject(), GameObjectTemplate::IsIgnoringLOSChecks(), Unit::IsMounted(), Object::IsPlayer(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, m_originalCasterGUID, m_spellFlags, m_spellInfo, m_targets, m_triggeredByAuraSpell, SPELL_ATTR2_IGNORE_LINE_OF_SIGHT, SPELL_AURA_AOE_CHARM, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_DISABLE_LOS, SPELL_EFFECT_RESURRECT_NEW, SPELL_EFFECT_SKIN_PLAYER_CORPSE, SPELL_EFFECT_SUMMON_RAF_FRIEND, SPELL_FLAG_REDIRECTED, TriggeredByAuraSpellData::spellInfo, sWorld, TARGET_CHECK_ENTRY, Object::ToPlayer(), Unit::ToTempSummon(), UNIT_FLAG_NOT_SELECTABLE, UNIT_FLAG_SKINNABLE, and WORLD_TRIGGER.

Referenced by AddUnitTarget().

◆ CheckItems()

SpellCastResult Spell::CheckItems ( )
Todo:
Needs review
Todo:
: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
7180{
7181 Player* player = m_caster->ToPlayer();
7182 if (!player)
7183 {
7184 // Non-player case: Check if creature is disarmed
7186 {
7188 }
7189
7190 return SPELL_CAST_OK;
7191 }
7192
7193 if (!m_CastItem)
7194 {
7195 if (m_castItemGUID)
7197 }
7198 else
7199 {
7200 uint32 itemid = m_CastItem->GetEntry();
7201 if (!player->HasItemCount(itemid))
7203
7204 ItemTemplate const* proto = m_CastItem->GetTemplate();
7205 if (!proto)
7207
7208 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7209 if (proto->Spells[i].SpellCharges)
7210 if (m_CastItem->GetSpellCharges(i) == 0)
7212
7213 // consumable cast item checks
7215 {
7216 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7217 SpellCastResult failReason = SPELL_CAST_OK;
7218 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7219 {
7220 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7221 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7222 continue;
7223
7224 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7225 {
7227 {
7229 continue;
7230 }
7231 else
7232 {
7233 failReason = SPELL_CAST_OK;
7234 break;
7235 }
7236 }
7237
7238 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7239 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7240 {
7241 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7242 {
7244 continue;
7245 }
7246
7247 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7249 {
7251 continue;
7252 }
7253 else
7254 {
7255 failReason = SPELL_CAST_OK;
7256 break;
7257 }
7258 }
7259 }
7260 if (failReason != SPELL_CAST_OK)
7261 return failReason;
7262 }
7263 }
7264
7265 // check target item
7267 {
7268 if (!m_caster->IsPlayer())
7270
7271 if (!m_targets.GetItemTarget())
7273
7276 }
7277 // if not item target then required item must be equipped
7278 else
7279 {
7280 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7281 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7284 }
7285
7286 // do not take reagents for these item casts
7288 {
7290 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7291 if (!checkReagents)
7292 if (Item* targetItem = m_targets.GetItemTarget())
7293 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7294 checkReagents = true;
7295
7296 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7297 if (checkReagents)
7298 {
7299 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7300 {
7301 if (m_spellInfo->Reagent[i] <= 0)
7302 continue;
7303
7304 uint32 itemid = m_spellInfo->Reagent[i];
7305 uint32 itemcount = m_spellInfo->ReagentCount[i];
7306
7307 // if CastItem is also spell reagent
7308 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7309 {
7310 ItemTemplate const* proto = m_CastItem->GetTemplate();
7311 if (!proto)
7313 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7314 {
7315 // CastItem will be used up and does not count as reagent
7316 int32 charges = m_CastItem->GetSpellCharges(s);
7317 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7318 {
7319 ++itemcount;
7320 break;
7321 }
7322 }
7323 }
7324 if (!player->HasItemCount(itemid, itemcount))
7325 return SPELL_FAILED_REAGENTS;
7326 }
7327 }
7328
7329 // check totem-item requirements (items presence in inventory)
7330 uint32 totems = 2;
7331 for (int i = 0; i < 2; ++i)
7332 {
7333 if (m_spellInfo->Totem[i] != 0)
7334 {
7335 if (player->HasItemCount(m_spellInfo->Totem[i]))
7336 {
7337 totems -= 1;
7338 continue;
7339 }
7340 }
7341 else
7342 totems -= 1;
7343 }
7344 if (totems != 0)
7345 return SPELL_FAILED_TOTEMS; //0x7C
7346
7347 // Check items for TotemCategory (items presence in inventory)
7349 for (int i = 0; i < 2; ++i)
7350 {
7351 if (m_spellInfo->TotemCategory[i] != 0)
7352 {
7354 {
7355 TotemCategory -= 1;
7356 continue;
7357 }
7358 }
7359 else
7360 TotemCategory -= 1;
7361 }
7362 if (TotemCategory != 0)
7363 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7364 }
7365
7366 // special checks for spell effects
7367 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7368 {
7369 switch (m_spellInfo->Effects[i].Effect)
7370 {
7373 {
7374 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7375 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7376 if (target->IsPlayer() && !IsTriggered())
7377 {
7378 // SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
7379 // so we need to make sure there is at least one free space in the player's inventory
7381 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7382 {
7383 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7385 }
7386
7387 if (m_spellInfo->Effects[i].ItemType)
7388 {
7389 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7390 if (!itemTemplate)
7392
7393 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7394 ItemPosCountVec dest;
7395 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7396 if (msg != EQUIP_ERR_OK)
7397 {
7399 if (!itemTemplate->ItemLimitCategory)
7400 {
7401 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7403 }
7404 else
7405 {
7406 // Conjure Food/Water/Refreshment spells
7409 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7410 {
7411 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7413 }
7414 else
7415 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7416
7418 }
7419 }
7420 }
7421 }
7422 break;
7423 }
7425 {
7426 if (player->GetFreeInventorySpace() == 0)
7427 {
7428 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7430 }
7431 break;
7432 }
7434 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7436 {
7437 // cannot enchant vellum for other player
7440 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7443 ItemPosCountVec dest;
7444 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7445 if (msg != EQUIP_ERR_OK)
7446 {
7447 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7449 }
7450 }
7451 [[fallthrough]];
7453 {
7454 Item* targetItem = m_targets.GetItemTarget();
7455 if (!targetItem)
7457
7458 // xinef: required level has to be checked also! Exploit fix
7459 if (targetItem->GetTemplate()->ItemLevel < m_spellInfo->BaseLevel || (targetItem->GetTemplate()->RequiredLevel && targetItem->GetTemplate()->RequiredLevel < m_spellInfo->BaseLevel))
7460 return SPELL_FAILED_LOWLEVEL;
7461
7462 bool isItemUsable = false;
7463 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7464 {
7465 ItemTemplate const* proto = targetItem->GetTemplate();
7466 if (proto->Spells[e].SpellId && (
7469 {
7470 isItemUsable = true;
7471 break;
7472 }
7473 }
7474
7475 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7476 // do not allow adding usable enchantments to items that have use effect already
7477 if (enchantEntry)
7478 {
7479 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7480 {
7481 switch (enchantEntry->type[s])
7482 {
7484 if (isItemUsable)
7486 break;
7488 {
7489 uint32 numSockets = 0;
7490 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7491 if (targetItem->GetTemplate()->Socket[socket].Color)
7492 ++numSockets;
7493
7494 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7496 break;
7497 }
7498 }
7499 }
7500 }
7501
7502 // Not allow enchant in trade slot for some enchant type
7503 if (targetItem->GetOwner() != m_caster)
7504 {
7505 if (!enchantEntry)
7506 return SPELL_FAILED_ERROR;
7507 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7509 }
7510 break;
7511 }
7513 {
7514 Item* item = m_targets.GetItemTarget();
7515 if (!item)
7517 // Not allow enchant in trade slot for some enchant type
7518 if (item->GetOwner() != m_caster)
7519 {
7520 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7521 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7522 if (!pEnchant)
7523 return SPELL_FAILED_ERROR;
7524 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7526 }
7527
7528 // Xinef: Apply item level restriction if the enchanting spell has max level restrition set
7529 if (m_CastItem && m_spellInfo->MaxLevel > 0)
7530 {
7532 return SPELL_FAILED_LOWLEVEL;
7533 if (item->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7535 }
7536
7537 break;
7538 }
7540 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7541 break;
7543 {
7544 if (!m_targets.GetItemTarget())
7546
7547 // prevent disenchanting in trade slot
7550
7551 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7552 if (!itemProto)
7554
7555 uint32 item_quality = itemProto->Quality;
7556 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7557 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7558 if (item_disenchantskilllevel == uint32(-1))
7560 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7562 if (item_quality > 4 || item_quality < 2)
7564 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7566 if (!itemProto->DisenchantID)
7568 break;
7569 }
7571 {
7572 if (!m_targets.GetItemTarget())
7574 //ensure item is a prospectable ore
7577 //prevent prospecting in trade slot
7580 //Check for enough skill in jewelcrafting
7581 uint32 item_prospectingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7582 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7584 //make sure the player has the required ores in inventory
7585 if (m_targets.GetItemTarget()->GetCount() < 5)
7587
7590
7591 break;
7592 }
7594 {
7595 if (!m_targets.GetItemTarget())
7597 //ensure item is a millable herb
7600 //prevent milling in trade slot
7603 //Check for enough skill in inscription
7604 uint32 item_millingskilllevel = m_targets.GetItemTarget()->GetTemplate()->RequiredSkillRank;
7605 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7607 //make sure the player has the required herbs in inventory
7608 if (m_targets.GetItemTarget()->GetCount() < 5)
7610
7613
7614 break;
7615 }
7618 {
7619 if (!m_caster->IsPlayer())
7621
7623 break;
7624
7626 if (!pItem || pItem->IsBroken())
7628
7629 switch (pItem->GetTemplate()->SubClass)
7630 {
7632 {
7633 uint32 ammo = pItem->GetEntry();
7634 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7635 return SPELL_FAILED_NO_AMMO;
7636 };
7637 break;
7641 {
7643 if (!ammo)
7644 {
7645 // Requires No Ammo
7646 if (m_caster->HasAura(46699))
7647 break; // skip other checks
7648
7649 return SPELL_FAILED_NO_AMMO;
7650 }
7651
7652 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7653 if (!ammoProto)
7654 return SPELL_FAILED_NO_AMMO;
7655
7656 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7657 return SPELL_FAILED_NO_AMMO;
7658
7659 // check ammo ws. weapon compatibility
7660 switch (pItem->GetTemplate()->SubClass)
7661 {
7664 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7665 return SPELL_FAILED_NO_AMMO;
7666 break;
7668 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7669 return SPELL_FAILED_NO_AMMO;
7670 break;
7671 default:
7672 return SPELL_FAILED_NO_AMMO;
7673 }
7674
7675 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7676 {
7678 return SPELL_FAILED_NO_AMMO;
7679 }
7680 };
7681 break;
7683 break;
7684 default:
7685 break;
7686 }
7687 break;
7688 }
7690 {
7691 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7692 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7693
7694 if (!pProto)
7696
7697 if (Item* pitem = player->GetItemByEntry(item_id))
7698 {
7699 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7700 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7702 }
7703 break;
7704 }
7705 default:
7706 break;
7707 }
7708 }
7709
7710 // check weapon presence in slots for main/offhand weapons
7711 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7712 {
7713 // main hand weapon required
7715 {
7717
7718 // skip spell if no weapon in slot or broken
7719 if (!item || item->IsBroken())
7721
7722 // skip spell if weapon not fit to triggered spell
7725 }
7726
7727 // offhand hand weapon required
7729 {
7731
7732 // skip spell if no weapon in slot or broken
7733 if (!item || item->IsBroken())
7735
7736 // skip spell if weapon not fit to triggered spell
7739 }
7740
7742 }
7743
7744 return SPELL_CAST_OK;
7745}
std::int8_t int8
Definition: Define.h:105
#define MAX_SPELL_REAGENTS
Definition: DBCStructure.h:1638
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition: DBCStructure.h:1837
@ ITEM_ENCHANTMENT_TYPE_USE_SPELL
Definition: DBCEnums.h:373
@ ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET
Definition: DBCEnums.h:374
@ EFFECT_1
Definition: SharedDefines.h:32
@ MAX_POWERS
Definition: SharedDefines.h:276
@ SPELL_EFFECT_DISENCHANT
Definition: SharedDefines.h:877
@ SPELL_EFFECT_PROSPECTING
Definition: SharedDefines.h:905
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition: SharedDefines.h:870
@ SPELL_EFFECT_ENCHANT_ITEM
Definition: SharedDefines.h:831
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition: SharedDefines.h:836
@ SPELL_EFFECT_HEAL
Definition: SharedDefines.h:788
@ SPELL_EFFECT_MILLING
Definition: SharedDefines.h:936
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition: SharedDefines.h:844
@ SPELL_EFFECT_CREATE_ITEM_2
Definition: SharedDefines.h:935
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition: SharedDefines.h:795
@ SPELL_EFFECT_ENERGIZE
Definition: SharedDefines.h:808
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition: SharedDefines.h:837
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition: SharedDefines.h:934
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition: SharedDefines.h:832
@ SPELL_EFFECT_CREATE_ITEM
Definition: SharedDefines.h:802
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition: SharedDefines.h:503
@ SPELLFAMILY_MAGE
Definition: SharedDefines.h:3531
TotemCategory
Definition: SharedDefines.h:3083
@ SPELL_FAILED_CANT_BE_MILLED
Definition: SharedDefines.h:965
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition: SharedDefines.h:980
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition: SharedDefines.h:978
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition: SharedDefines.h:1128
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition: SharedDefines.h:1071
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition: SharedDefines.h:953
@ SPELL_FAILED_NOT_TRADEABLE
Definition: SharedDefines.h:1019
@ SPELL_FAILED_ITEM_NOT_READY
Definition: SharedDefines.h:994
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition: SharedDefines.h:1025
@ SPELL_FAILED_ITEM_GONE
Definition: SharedDefines.h:992
@ SPELL_FAILED_NO_AMMO
Definition: SharedDefines.h:1024
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition: SharedDefines.h:993
@ SPELL_FAILED_EQUIPPED_ITEM
Definition: SharedDefines.h:977
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition: SharedDefines.h:951
@ SPELL_FAILED_ON_USE_ENCHANT
Definition: SharedDefines.h:1119
@ SPELL_FAILED_TOTEMS
Definition: SharedDefines.h:1080
@ SPELL_FAILED_ERROR
Definition: SharedDefines.h:981
@ SPELL_FAILED_REAGENTS
Definition: SharedDefines.h:1049
@ SPELL_FAILED_MAX_SOCKETS
Definition: SharedDefines.h:1133
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition: SharedDefines.h:963
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition: SharedDefines.h:1078
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition: SharedDefines.h:1004
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition: SharedDefines.h:966
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition: SharedDefines.h:979
@ SPELL_FAILED_TOTEM_CATEGORY
Definition: SharedDefines.h:1079
@ SKILL_INSCRIPTION
Definition: SharedDefines.h:3002
@ SKILL_ENCHANTING
Definition: SharedDefines.h:2954
@ SKILL_JEWELCRAFTING
Definition: SharedDefines.h:2985
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:771
InventoryResult
Definition: Item.h:46
@ EQUIP_ERR_OK
Definition: Item.h:47
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:97
#define MAX_ITEM_SPELLS
Definition: Item.h:215
@ ENCHANTMENT_CAN_SOULBOUND
Definition: Item.h:201
@ NULL_BAG
Definition: Item.h:40
@ NULL_SLOT
Definition: Item.h:41
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:175
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:362
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:347
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:346
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:363
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:360
@ ITEM_SPELLTRIGGER_ON_USE
Definition: ItemTemplate.h:77
@ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE
Definition: ItemTemplate.h:87
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:176
@ ITEM_FLAG_NO_REAGENT_COST
Definition: ItemTemplate.h:175
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:165
@ ITEM_SUBCLASS_ARROW
Definition: ItemTemplate.h:416
@ ITEM_SUBCLASS_BULLET
Definition: ItemTemplate.h:417
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:614
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:615
@ ITEM_CLASS_PROJECTILE
Definition: ItemTemplate.h:297
@ ITEM_CLASS_ARMOR
Definition: ItemTemplate.h:295
@ ITEM_CLASS_WEAPON
Definition: ItemTemplate.h:293
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:291
@ PLAYER_AMMO_ID
Definition: UpdateFields.h:369
LootStore LootTemplates_Milling("milling_loot_template", "item entry (herb)", true)
LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry (ore)", true)
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:317
bool IsBroken() const
Definition: Item.h:257
bool IsWeaponVellum() const
Definition: Item.h:338
bool IsArmorVellum() const
Definition: Item.h:339
Player * GetOwner() const
Definition: Item.cpp:549
ObjectGuid GetOwnerGUID() const
Definition: Item.h:231
uint32 GetCount() const
Definition: Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition: Item.cpp:884
int32 SpellCharges
Definition: ItemTemplate.h:593
uint32 SpellTrigger
Definition: ItemTemplate.h:592
int32 SpellId
Definition: ItemTemplate.h:591
uint32 Color
Definition: ItemTemplate.h:602
Definition: ItemTemplate.h:619
uint32 DisenchantID
Definition: ItemTemplate.h:690
uint32 Quality
Definition: ItemTemplate.h:626
uint32 RequiredSkillRank
Definition: ItemTemplate.h:638
uint32 GetMaxStackSize() const
Definition: ItemTemplate.h:729
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:662
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:684
uint32 RequiredLevel
Definition: ItemTemplate.h:636
bool HasFlag(ItemFlags flag) const
Definition: ItemTemplate.h:827
uint32 Class
Definition: ItemTemplate.h:621
uint32 ItemLimitCategory
Definition: ItemTemplate.h:687
uint32 SubClass
Definition: ItemTemplate.h:622
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:681
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition: Player.cpp:12525
uint32 GetFreeInventorySpace() const
Definition: PlayerStorage.cpp:466
Item * GetItemByEntry(uint32 entry) const
Definition: PlayerStorage.cpp:3369
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition: PlayerStorage.cpp:655
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition: PlayerStorage.cpp:851
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition: Player.cpp:12570
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition: PlayerStorage.cpp:4021
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1274
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.h:936
bool IsFullHealth() const
Definition: Unit.h:1035
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1057
void SetUInt32Value(uint16 index, uint32 value)
Definition: Unit.cpp:21312
uint32 GetPower(Powers power) const
Definition: Unit.h:1056
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:223
uint32 GetItemTargetEntry() const
Definition: Spell.h:142
ObjectGuid m_castItemGUID
Definition: Spell.h:525
uint32 BaseLevel
Definition: SpellInfo.h:359
uint32 MaxLevel
Definition: SpellInfo.h:358
std::array< int32, MAX_SPELL_REAGENTS > Reagent
Definition: SpellInfo.h:373
flag96 SpellFamilyFlags
Definition: SpellInfo.h:388
std::array< uint32, 2 > TotemCategory
Definition: SpellInfo.h:378
int32 EquippedItemClass
Definition: SpellInfo.h:375
std::array< uint32, 2 > Totem
Definition: SpellInfo.h:372
std::array< uint32, MAX_SPELL_REAGENTS > ReagentCount
Definition: SpellInfo.h:374
Definition: DBCStructure.h:1840
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition: DBCStructure.h:1843
uint32 slot
Definition: DBCStructure.h:1850

References BASE_ATTACK, SpellInfo::BaseLevel, Player::CanNoReagentCast(), Player::CanStoreNewItem(), Unit::CanUseAttackType(), Unit::CastSpell(), ItemTemplate::Class, _Socket::Color, ItemTemplate::DisenchantID, SpellInfo::DmgClass, EFFECT_1, SpellInfo::Effects, ENCHANTMENT_CAN_SOULBOUND, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_OK, SpellInfo::EquippedItemClass, Item::GetCount(), Item::GetEnchantmentId(), Object::GetEntry(), Player::GetFreeInventorySpace(), Object::GetGUID(), Player::GetItemByEntry(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetItemTargetEntry(), SpellCastTargets::GetItemTargetGUID(), Unit::GetMaxPower(), ItemTemplate::GetMaxStackSize(), Item::GetOwner(), Item::GetOwnerGUID(), Unit::GetPower(), Player::GetSkillValue(), Item::GetSpellCharges(), Item::GetTemplate(), Object::GetUInt32Value(), SpellCastTargets::GetUnitTarget(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), ItemTemplate::HasFlag(), Player::HasItemCount(), Player::HasItemFitToSpellRequirements(), Player::HasItemTotemCategory(), HasTriggeredCastFlag(), LootStore::HaveLootFor(), Item::IsArmorVellum(), Item::IsBroken(), Item::IsFitToSpellRequirements(), Unit::IsFullHealth(), Object::IsPlayer(), IsTriggered(), Item::IsWeaponVellum(), ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE, ITEM_CLASS_PROJECTILE, ITEM_CLASS_WEAPON, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, ITEM_ENCHANTMENT_TYPE_USE_SPELL, ITEM_FLAG_IS_MILLABLE, ITEM_FLAG_IS_PROSPECTABLE, ITEM_FLAG_NO_REAGENT_COST, ITEM_SPELLTRIGGER_ON_NO_DELAY_USE, ITEM_SPELLTRIGGER_ON_USE, ITEM_SUBCLASS_ARROW, ITEM_SUBCLASS_BULLET, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, ITEM_SUBCLASS_WEAPON_WAND, ItemTemplate::ItemLevel, ItemTemplate::ItemLimitCategory, LootTemplates_Milling, LootTemplates_Prospecting, m_attackType, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, m_weaponItem, MAX_ITEM_PROTO_SOCKETS, MAX_ITEM_PROTO_SPELLS, MAX_ITEM_SPELLS, MAX_POWERS, MAX_SPELL_EFFECTS, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::MaxLevel, NULL_BAG, NULL_SLOT, OFF_ATTACK, PLAYER_AMMO_ID, PRISMATIC_ENCHANTMENT_SLOT, ItemTemplate::Quality, RANGED_ATTACK, SpellInfo::Reagent, SpellInfo::ReagentCount, ItemTemplate::RequiredDisenchantSkill, ItemTemplate::RequiredLevel, ItemTemplate::RequiredSkillRank, Player::SendEquipError(), Unit::SetUInt32Value(), SKILL_ENCHANTING, SKILL_INSCRIPTION, SKILL_JEWELCRAFTING, SpellItemEnchantmentEntry::slot, sObjectMgr, ItemTemplate::Socket, SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON, SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_CREATE_ITEM_2, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_ENCHANT_HELD_ITEM, SPELL_EFFECT_ENCHANT_ITEM, SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_HEAL, SPELL_EFFECT_MILLING, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_FAILED_ALREADY_AT_FULL_HEALTH, SPELL_FAILED_ALREADY_AT_FULL_POWER, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_BE_DISENCHANTED, SPELL_FAILED_CANT_BE_MILLED, SPELL_FAILED_CANT_BE_PROSPECTED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_EQUIPPED_ITEM, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_ERROR, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_ITEM_AT_MAX_CHARGES, SPELL_FAILED_ITEM_GONE, SPELL_FAILED_ITEM_NOT_FOUND, SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_LOW_CASTLEVEL, SPELL_FAILED_LOWLEVEL, SPELL_FAILED_MAX_SOCKETS, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_NO_AMMO, SPELL_FAILED_NO_CHARGES_REMAIN, SPELL_FAILED_NOT_TRADEABLE, SPELL_FAILED_ON_USE_ENCHANT, SPELL_FAILED_REAGENTS, SPELL_FAILED_TARGET_NOT_PLAYER, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, _Spell::SpellCharges, SPELLFAMILY_MAGE, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, _Spell::SpellId, ItemTemplate::Spells, _Spell::SpellTrigger, sSpellItemEnchantmentStore, ItemTemplate::SubClass, TARGET_UNIT_PET, Object::ToPlayer(), SpellInfo::Totem, SpellInfo::TotemCategory, TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, and SpellItemEnchantmentEntry::type.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit target)
6816{
6817 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6819
6820 // dead owner (pets still alive when owners ressed?)
6821 if (Unit* owner = m_caster->GetCharmerOrOwner())
6822 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6824
6825 if (!target && m_targets.GetUnitTarget())
6826 target = m_targets.GetUnitTarget();
6827
6829 {
6830 if (!target)
6832 m_targets.SetUnitTarget(target);
6833 }
6834
6835 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6837
6838 // cooldown
6839 if (Creature const* creatureCaster = m_caster->ToCreature())
6840 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6842
6843 // Check if spell is affected by GCD
6847
6848 return CheckCast(true);
6849}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition: CharmInfo.cpp:397
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:239
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:2401
uint32 StartRecoveryCategory
Definition: SpellInfo.h:350

References SpellInfo::CalcPowerCost(), CheckCast(), Unit::GetCharmerOrOwner(), Unit::GetCharmInfo(), Object::GetEntry(), CharmInfo::GetGlobalCooldownMgr(), SpellCastTargets::GetUnitTarget(), GlobalCooldownMgr::HasGlobalCooldown(), HasTriggeredCastFlag(), Unit::HasUnitState(), SpellInfo::Id, m_caster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_targets, SpellInfo::NeedsExplicitUnitTarget(), SpellCastTargets::SetUnitTarget(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS, SpellInfo::StartRecoveryCategory, Object::ToCreature(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

Referenced by CanAutoCast(), WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7135{
7136 // item cast not used power
7137 if (m_CastItem)
7138 return SPELL_CAST_OK;
7139
7140 //While .cheat power is enabled dont check if we need power to cast the spell
7141 if (m_caster->IsPlayer())
7142 {
7144 {
7145 return SPELL_CAST_OK;
7146 }
7147 }
7148
7149 // health as power used - need check health amount
7151 {
7154 return SPELL_CAST_OK;
7155 }
7156 // Check valid power type
7158 {
7159 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7160 return SPELL_FAILED_UNKNOWN;
7161 }
7162
7163 //check rune cost only if a spell has PowerType == POWER_RUNE
7165 {
7167 if (failReason != SPELL_CAST_OK)
7168 return failReason;
7169 }
7170
7171 // Check power amount
7174 return SPELL_FAILED_NO_POWER;
7175 else
7176 return SPELL_CAST_OK;
7177}
@ POWER_HEALTH
Definition: SharedDefines.h:278
@ POWER_RUNE
Definition: SharedDefines.h:274
@ SPELL_FAILED_NO_POWER
Definition: SharedDefines.h:1034
@ SPELL_FAILED_UNKNOWN
Definition: SharedDefines.h:1136
@ CHEAT_POWER
Definition: Player.h:1002
PowerType
Definition: VehicleDefines.h:29
uint32 GetHealth() const
Definition: Unit.h:1029
SpellCastResult CheckRuneCost(uint32 RuneCostID)
Definition: Spell.cpp:5409
uint32 RuneCostID
Definition: SpellInfo.h:368
uint32 PowerType
Definition: SpellInfo.h:362

References CHEAT_POWER, CheckRuneCost(), Player::GetCommandStatus(), Unit::GetHealth(), Unit::GetPower(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, MAX_POWERS, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, SPELL_CAST_OK, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_NO_POWER, SPELL_FAILED_UNKNOWN, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7049{
7050 // Don't check for instant cast spells
7051 if (!strict && m_casttime == 0)
7052 return SPELL_CAST_OK;
7053
7054 uint32 range_type = 0;
7055
7057 {
7058 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7059 // these are triggered by other spells - possibly we should omit range check in that case?
7060 if (m_spellInfo->RangeEntry->ID == 1)
7061 return SPELL_CAST_OK;
7062
7063 range_type = m_spellInfo->RangeEntry->Flags;
7064 }
7065
7066 Unit* target = m_targets.GetUnitTarget();
7067 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7068 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7069
7070 // xinef: hack for npc shooters
7071 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7072 range_type = SPELL_RANGE_RANGED;
7073
7074 if (Player* modOwner = m_caster->GetSpellModOwner())
7075 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7076
7077 // xinef: dont check max_range to strictly after cast
7078 if (range_type != SPELL_RANGE_MELEE && !strict)
7079 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7080
7081 if (target)
7082 {
7083 if (target != m_caster)
7084 {
7085 // Xinef: Spells with 5yd range can hit target 9yd away?
7086 if (range_type == SPELL_RANGE_MELEE)
7087 {
7088 float real_max_range = max_range;
7089 if (!m_caster->IsCreature() && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking())
7090 real_max_range -= MIN_MELEE_REACH; // Because of lag, we can not check too strictly here (is only used if both caster and target are moving)
7091 else
7092 real_max_range -= 2 * MIN_MELEE_REACH;
7093
7094 if (!m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7096 }
7097 else if (!m_caster->IsWithinCombatRange(target, max_range))
7098 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7099
7101 {
7102 if (m_caster->IsWithinMeleeRange(target))
7104 }
7105
7106 if (m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
7108 }
7109
7110 // Xinef: check min range for self casts
7111 if (min_range && range_type != SPELL_RANGE_RANGED && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
7113 }
7114
7115 if (GameObject* goTarget = m_targets.GetGOTarget())
7116 {
7117 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7118 {
7120 }
7121 }
7122
7123 if (m_targets.HasDst() && !m_targets.HasTraj())
7124 {
7125 if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
7127 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7129 }
7130
7131 return SPELL_CAST_OK;
7132}
@ SPELL_FAILED_TOO_CLOSE
Definition: SharedDefines.h:1077
@ SPELL_FAILED_OUT_OF_RANGE
Definition: SharedDefines.h:1046
@ SPELL_RANGE_MELEE
Definition: Spell.h:91
@ SPELL_RANGE_RANGED
Definition: Spell.h:92
@ SPELLMOD_RANGE
Definition: SpellDefines.h:81
@ SPELL_FACING_FLAG_INFRONT
Definition: SpellDefines.h:125
#define MIN_MELEE_REACH
Definition: ObjectDefines.h:47
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition: Object.cpp:1295
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:141
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition: Unit.cpp:648
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15162
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition: Unit.cpp:664
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Unit.cpp:15142
bool IsWalking() const
Definition: Unit.h:1576
Unit * GetCaster() const
Definition: Spell.h:575
SpellRangeEntry const * RangeEntry
Definition: SpellInfo.h:369
uint32 FacingCasterFlags
Definition: SpellInfo.h:338
uint32 Flags
Definition: DBCStructure.h:1796
uint32 ID
Definition: DBCStructure.h:1793

References SpellInfo::DmgClass, SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, GetCaster(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::HasDst(), Position::HasInArc(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsWalking(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist3d(), Unit::IsWithinMeleeRange(), m_caster, m_casttime, m_spellInfo, m_targets, MIN_MELEE_REACH, SpellInfo::RangeEntry, SPELL_CAST_OK, SPELL_DAMAGE_CLASS_RANGED, SPELL_FACING_FLAG_INFRONT, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_TOO_CLOSE, SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_RANGE_MELEE, SPELL_RANGE_RANGED, SPELLMOD_RANGE, and Object::ToPlayer().

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5410{
5411 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5412 return SPELL_CAST_OK;
5413
5414 if (!m_caster->IsPlayer())
5415 return SPELL_CAST_OK;
5416
5417 Player* player = m_caster->ToPlayer();
5418 //If we are in .cheat power mode we dont need to check the cost as we are expected to be able to use it anyways (infinite power)
5419 if (player->GetCommandStatus(CHEAT_POWER))
5420 {
5421 return SPELL_CAST_OK;
5422 }
5423
5425 return SPELL_CAST_OK;
5426
5427 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5428
5429 if (!src)
5430 return SPELL_CAST_OK;
5431
5432 if (src->NoRuneCost())
5433 return SPELL_CAST_OK;
5434
5435 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5436
5437 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5438 {
5439 runeCost[i] = src->RuneCost[i];
5440 if (Player* modOwner = m_caster->GetSpellModOwner())
5441 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5442 }
5443
5444 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5445
5446 for (uint32 i = 0; i < MAX_RUNES; ++i)
5447 {
5448 RuneType rune = player->GetCurrentRune(i);
5449 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5450 runeCost[rune]--;
5451 }
5452
5453 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5454 if (runeCost[i] > 0)
5455 runeCost[RUNE_DEATH] += runeCost[i];
5456
5457 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5458 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5459
5460 return SPELL_CAST_OK;
5461}
@ CLASS_DEATH_KNIGHT
Definition: SharedDefines.h:146
@ SPELLMOD_COST
Definition: SpellDefines.h:90
RuneType
Definition: Player.h:408
@ RUNE_DEATH
Definition: Player.h:412
@ NUM_RUNE_TYPES
Definition: Player.h:413
#define MAX_RUNES
Definition: Player.h:398
@ CLASS_CONTEXT_ABILITY
Definition: UnitDefines.h:213
DBCStorage< SpellRuneCostEntry > sSpellRuneCostStore(SpellRuneCostfmt)
uint32 GetRuneCooldown(uint8 index) const
Definition: Player.h:2491
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition: Player.cpp:1281
RuneType GetCurrentRune(uint8 index) const
Definition: Player.h:2490
Definition: DBCStructure.h:1804
uint32 RuneCost[3]
Definition: DBCStructure.h:1806
bool NoRuneCost() const
Definition: DBCStructure.h:1809

References CHEAT_POWER, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetCommandStatus(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_RUNES, SpellRuneCostEntry::NoRuneCost(), NUM_RUNE_TYPES, POWER_RUNE, SpellInfo::PowerType, RUNE_DEATH, SpellRuneCostEntry::RuneCost, SPELL_CAST_OK, SPELL_FAILED_NO_POWER, SPELLMOD_COST, sSpellRuneCostStore, and Object::ToPlayer().

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
8713{
8714 // Skip if there are not any script
8715 if (!m_loadedScripts.size())
8716 return true;
8717
8718 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8719 {
8720 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8721 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8722 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8723 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8724 return false;
8725
8726 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8727 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8728 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8729 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8730 return false;
8731 }
8732 return true;
8733}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7748{
7749 // check spell focus object
7751 {
7753 Cell cell(p);
7754
7755 GameObject* ok = nullptr;
7758
7760 Map& map = *m_caster->GetMap();
7761 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7762
7763 if (!ok)
7765
7766 focusObject = ok; // game object found in range
7767 }
7768 return SPELL_CAST_OK;
7769}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition: SharedDefines.h:1051
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:190
Definition: TypeContainer.h:100
Definition: TypeContainerVisitor.h:84
Definition: Cell.h:45
Definition: GridNotifiers.h:319
Definition: GridNotifiers.h:657
Definition: Map.h:311
void Visit(const Cell &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition: Map.h:871
uint32 RequiresSpellFocus
Definition: SpellInfo.h:337

References Acore::ComputeCellCoord(), focusObject, WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetVisibilityRange(), m_caster, m_spellInfo, SpellInfo::RequiresSpellFocus, SPELL_CAST_OK, SPELL_FAILED_REQUIRES_SPELL_FOCUS, and Cell::Visit().

Referenced by CheckCast().

◆ CheckSrc()

void Spell::CheckSrc ( )
inline
bool HasSrc() const
Definition: Spell.h:166
void SetSrc(float x, float y, float z)
Definition: Spell.cpp:367

References SpellCastTargets::HasSrc(), m_caster, m_targets, and SpellCastTargets::SetSrc().

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2372{
2373 m_UniqueTargetInfo.clear();
2374 m_UniqueGOTargetInfo.clear();
2375 m_UniqueItemInfo.clear();
2376 m_delayMoment = 0;
2378}
uint64 m_delayTrajectory
Definition: Spell.h:642

References m_delayMoment, m_delayTrajectory, m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

Referenced by spell_dk_raise_dead::CheckCast(), and Spell().

◆ Delayed()

void Spell::Delayed ( )
7772{
7773 if (!m_caster)// || !m_caster->IsPlayer())
7774 return;
7775
7776 //if (m_spellState == SPELL_STATE_DELAYED)
7777 // return; // spell is active and can't be time-backed
7778
7779 if (isDelayableNoMore()) // Spells may only be delayed twice
7780 return;
7781
7783 return;
7784
7785 // spells not loosing casting time (slam, dynamites, bombs..)
7786 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7787 // return;
7788
7789 //check pushback reduce
7790 int32 delaytime = 500; // spellcasting delay is normally 500ms
7791 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7794 if (delayReduce >= 100)
7795 return;
7796
7797 AddPct(delaytime, -delayReduce);
7798
7799 if (m_timer + delaytime > m_casttime)
7800 {
7801 delaytime = m_casttime - m_timer;
7803 }
7804 else
7805 m_timer += delaytime;
7806
7807 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7808
7809 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7810 data << m_caster->GetPackGUID();
7811 data << uint32(delaytime);
7812
7813 m_caster->SendMessageToSet(&data, true);
7814}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:169
T AddPct(T &base, U pct)
Definition: Util.h:67
@ SPELL_ATTR6_NO_PUSHBACK
Definition: SharedDefines.h:619
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition: SpellDefines.h:85
@ SPELL_AURA_REDUCE_PUSHBACK
Definition: SpellAuraDefines.h:212
@ SMSG_SPELL_DELAYED
Definition: Opcodes.h:512
PackedGuid const & GetPackGUID() const
Definition: Object.h:111
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:2080
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition: Player.cpp:9739
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:5910
Definition: WorldPacket.h:26
bool isDelayableNoMore()
Definition: Spell.h:630

References AddPct(), Player::ApplySpellMod(), Object::GetPackGUID(), Unit::GetTotalAuraModifier(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_timer, WorldObject::SendMessageToSet(), SMSG_SPELL_DELAYED, SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
7817{
7819 return;
7820
7821 if (isDelayableNoMore()) // Spells may only be delayed twice
7822 return;
7823
7825 return;
7826
7827 //check pushback reduce
7828 // should be affected by modifiers, not take the dbc duration.
7830
7831 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7832 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7835 if (delayReduce >= 100)
7836 return;
7837
7838 AddPct(delaytime, -delayReduce);
7839
7840 if (m_timer <= delaytime)
7841 {
7842 delaytime = m_timer;
7843 m_timer = 0;
7844 }
7845 else
7846 m_timer -= delaytime;
7847
7848 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7849
7850 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7851 if ((*ihit).missCondition == SPELL_MISS_NONE)
7852 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7853 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7854
7855 // partially interrupt persistent area auras
7857 dynObj->Delay(delaytime);
7858
7860}
T CalculatePct(T base, U pct)
Definition: Util.h:61
Definition: DynamicObject.h:35
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6128
uint32 getState() const
Definition: Spell.h:484
int32 GetDuration() const
Definition: SpellInfo.cpp:2338

References AddPct(), Player::ApplySpellMod(), CalculatePct(), SpellInfo::GetDuration(), Unit::GetDynObject(), Object::GetGUID(), getState(), Unit::GetTotalAuraModifier(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, isDelayableNoMore(), Object::IsPlayer(), LOG_DEBUG, m_caster, m_channeledDuration, m_originalCasterGUID, m_spellInfo, m_timer, m_UniqueTargetInfo, SendChannelUpdate(), SPELL_ATTR6_NO_PUSHBACK, SPELL_AURA_REDUCE_PUSHBACK, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELLMOD_NOT_LOSE_CASTING_TIME, and Object::ToPlayer().

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8300{
8301 Unit* unit = nullptr;
8302 // In case spell hit target, do all effect on that target
8303 if (targetInfo.missCondition == SPELL_MISS_NONE)
8304 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8305 // In case spell reflect from target, do all effect on caster (if hit)
8306 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8307 unit = m_caster;
8308 if (!unit)
8309 return;
8310
8311 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8312 {
8313 if (targetInfo.effectMask & (1 << i))
8314 {
8315 m_damage = 0;
8316 m_healing = 0;
8317
8318 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8319
8320 if (m_damage > 0)
8321 {
8322 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8323 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8324 {
8326 if (m_caster->IsPlayer())
8327 {
8328 uint32 targetAmount = m_UniqueTargetInfo.size();
8329 if (targetAmount > 10)
8330 m_damage = m_damage * 10 / targetAmount;
8331 }
8332 }
8333 }
8334
8335 if (m_applyMultiplierMask & (1 << i))
8336 {
8338 m_damageMultipliers[i] *= multiplier[i];
8339 }
8340 targetInfo.damage += m_damage;
8341 }
8342 }
8343
8344 // xinef: totem's inherit owner crit chance and dancing rune weapon
8345 Unit* caster = m_caster;
8346 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8347 {
8348 if (Unit* owner = m_caster->GetOwner())
8349 caster = owner;
8350 }
8351 else if (m_originalCaster)
8352 caster = m_originalCaster;
8353
8354 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8355 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8356 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8357}
bool roll_chance_f(float chance)
Definition: Random.h:53
float SpellTakenCritChance(Unit const *caster, SpellInfo const *spellProto, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:12064
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition: Unit.cpp:11989
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, Unit *caster) const
Definition: Unit.cpp:20390
uint32 SchoolMask
Definition: SpellInfo.h:392

References Unit::CalculateAOEDamageReduction(), TargetInfo::crit, TargetInfo::damage, SpellInfo::DmgClass, TargetInfo::effectMask, SpellInfo::Effects, Object::GetEntry(), Object::GetGUID(), Unit::GetOwner(), ObjectAccessor::GetUnit(), HandleEffects(), Object::IsPlayer(), Unit::IsTotem(), m_applyMultiplierMask, m_attackType, m_caster, m_damage, m_damageMultipliers, m_healing, m_originalCaster, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::reflectResult, roll_chance_f(), SpellInfo::SchoolMask, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_MISS_NONE, SPELL_MISS_REFLECT, Unit::SpellDoneCritChance(), Unit::SpellTakenCritChance(), and TargetInfo::targetGUID.

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo target)
protected
3342{
3343 if (target->processed) // Check target
3344 return;
3345 target->processed = true; // Target checked in apply effects procedure
3346
3347 uint32 effectMask = target->effectMask;
3348 if (!effectMask)
3349 return;
3350
3351 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3352 if (!go)
3353 return;
3354
3357
3358 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3359 if (effectMask & (1 << effectNumber))
3360 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3361
3362 // xinef: inform ai about spellhit
3364
3366
3368}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: GameObjectAI.h:66
GameObjectAI * AI() const
Definition: GameObject.h:306
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition: Spell.cpp:8631
void CallScriptOnHitHandlers()
Definition: Spell.cpp:8644
void CallScriptAfterHitHandlers()
Definition: Spell.cpp:8657

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), Spell::GOTargetInfo::processed, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_MISS_NONE, GameObjectAI::SpellHit(), and Spell::GOTargetInfo::targetGUID.

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo target)
protected
3371{
3372 uint32 effectMask = target->effectMask;
3373 if (!target->item || !effectMask)
3374 return;
3375
3378
3379 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3380 if (effectMask & (1 << effectNumber))
3381 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3382
3384
3386}

References CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::ItemTargetInfo::effectMask, HandleEffects(), Spell::ItemTargetInfo::item, MAX_SPELL_EFFECTS, PrepareScriptHitHandlers(), SPELL_EFFECT_HANDLE_HIT_TARGET, and SPELL_MISS_NONE.

◆ DoAllEffectOnTarget() [3/3]

void Spell::DoAllEffectOnTarget ( TargetInfo target)
protected
Todo:
: check how broad this rule should be
2610{
2611 if (!target || target->processed)
2612 return;
2613
2614 target->processed = true; // Target checked in apply effects procedure
2615
2616 // Get mask of effects for target
2617 uint8 mask = target->effectMask;
2618
2619 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2620 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2621 return;
2622
2623 if (!effectUnit || m_spellInfo->Id == 45927)
2624 {
2625 uint8 farMask = 0;
2626 // create far target mask
2627 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2628 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2629 if ((1 << i) & mask)
2630 farMask |= (1 << i);
2631
2632 if (!farMask)
2633 return;
2634 // find unit in world
2635 // Xinef: FindUnit Access without Map check!!! Intended
2636 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2637 if (!effectUnit)
2638 return;
2639
2640 // do far effects on the unit
2641 // can't use default call because of threading, do stuff as fast as possible
2642 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2643 if (farMask & (1 << i))
2644 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2645 return;
2646 }
2647
2648 if (effectUnit->IsAlive() != target->alive)
2649 return;
2650
2651 // Xinef: absorb delayed projectiles for 500ms
2653 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime && GameTime::GetGameTimeMS().count() < (effectUnit->m_lastSanctuaryTime + 500) &&
2654 effectUnit->FindMap() && !effectUnit->FindMap()->IsDungeon()
2655 )
2656 return; // No missinfo in that case
2657
2658 // Get original caster (if exist) and calculate damage/healing from him data
2660
2661 // Skip if m_originalCaster not avaiable
2662 if (!caster)
2663 return;
2664
2665 SpellMissInfo missInfo = target->missCondition;
2666
2667 // Need init unitTarget by default unit (can changed in code on reflect)
2668 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2669 unitTarget = effectUnit;
2670
2671 // Reset damage/healing counter
2672 m_damage = target->damage;
2673 m_healing = -target->damage;
2674
2675 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2676
2679
2680 //Spells with this flag cannot trigger if effect is casted on self
2682 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2683 Unit* spellHitTarget = nullptr;
2684
2685 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2686 spellHitTarget = unitTarget;
2687 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2688 {
2689 missInfo = target->reflectResult;
2690 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2691 {
2692 spellHitTarget = m_caster;
2694 if (m_caster->IsCreature())
2696 }
2697 }
2698
2699 if (spellHitTarget)
2700 {
2701 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2702 if (missInfo2 != SPELL_MISS_NONE)
2703 {
2704 if (missInfo2 != SPELL_MISS_MISS)
2705 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2706 m_damage = 0;
2707 spellHitTarget = nullptr;
2708
2709 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2710 if (missInfo2 == SPELL_MISS_EVADE)
2711 missInfo = SPELL_MISS_EVADE;
2712 }
2713 }
2714
2715 // Do not take combo points on dodge and miss
2716 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2717 {
2718 m_needComboPoints = false;
2719 // Restore spell mods for a miss/dodge/parry Cold Blood
2721 if (m_caster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2722 m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
2723 }
2724
2725 // Fill base trigger info
2726 uint32 procAttacker = m_procAttacker;
2727 uint32 procVictim = m_procVictim;
2728 uint32 procEx = m_procEx;
2729
2730 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2731 if (canEffectTrigger && !procAttacker && !procVictim)
2732 {
2733 bool positive = true;
2734 if (m_damage > 0)
2735 positive = false;
2736 else if (!m_healing)
2737 {
2738 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2739 // If at least one effect negative spell is negative hit
2740 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2741 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2742 {
2743 positive = false;
2744 break;
2745 }
2746 }
2747 switch (m_spellInfo->DmgClass)
2748 {
2750 if (positive)
2751 {
2754 }
2755 else
2756 {
2759 }
2760 break;
2762 if (positive)
2763 {
2766 }
2767 else
2768 {
2771 }
2772 break;
2773 }
2774 }
2776
2777 // All calculated do it!
2778 // Do healing and triggers
2779 if (m_healing > 0)
2780 {
2781 bool crit = target->crit;
2782 uint32 addhealth = m_healing;
2783
2784 if (crit)
2785 {
2786 procEx |= PROC_EX_CRITICAL_HIT;
2787 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2788 }
2789 else
2790 procEx |= PROC_EX_NORMAL_HIT;
2791
2792 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2793
2794 // Xinef: override with forced crit, only visual result
2795 if (GetSpellValue()->ForcedCritResult)
2796 {
2797 crit = true;
2798 procEx |= PROC_EX_CRITICAL_HIT;
2799 }
2800
2801 int32 gain = caster->HealBySpell(healInfo, crit);
2802 unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
2803 m_healing = gain;
2804
2805 // Xinef: if heal acutally healed something, add no overheal flag
2806 if (m_healing)
2807 procEx |= PROC_EX_NO_OVERHEAL;
2808
2809 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2810 if (canEffectTrigger)
2811 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2812 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2813 }
2814 // Do damage and triggers
2815 else if (m_damage > 0)
2816 {
2818
2819 // Fill base damage struct (unitTarget - is real spell target)
2821
2822 // Add bonuses and fill damageInfo struct
2823 // Dancing Rune Weapon...
2824 if (m_caster->GetEntry() == 27893)
2825 {
2826 if (Unit* owner = m_caster->GetOwner())
2827 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2828 }
2829 else
2830 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2831
2832 // xinef: override miss info after absorb / block calculations
2833 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2834 {
2835 //if (damageInfo.absorb > 0)
2836 // missInfo = SPELL_MISS_ABSORB;
2837 if (damageInfo.blocked)
2838 missInfo = SPELL_MISS_BLOCK;
2839 }
2840
2841 // Xinef: override with forced crit, only visual result
2842 if (GetSpellValue()->ForcedCritResult)
2843 {
2844 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2845 }
2846
2847 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2848
2849 // xinef: health leech handling
2851 {
2852 uint8 effIndex = EFFECT_0;
2853 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2854 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2855 break;
2856
2857 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2858
2859 // get max possible damage, don't count overkill for heal
2860 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2861
2862 if (m_caster->IsAlive())
2863 {
2864 healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effIndex);
2865 healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
2866
2867 HealInfo healInfo(m_caster, m_caster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2868 m_caster->HealBySpell(healInfo);
2869 }
2870 }
2871
2872 // Send log damage message to client
2873 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2874 // Xinef: send info to target about reflect
2875 if (reflectedSpell)
2876 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2877
2878 procEx |= createProcExtendMask(&damageInfo, missInfo);
2879 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2880
2881 caster->DealSpellDamage(&damageInfo, true, this);
2882
2883 // do procs after damage, eg healing effects
2884 // no need to check if target is alive, done in procdamageandspell
2885
2886 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2887 if (canEffectTrigger)
2888 {
2889 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE);
2890 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2891 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2892
2895 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
2896 }
2897
2898 m_damage = damageInfo.damage;
2899 }
2900 // Passive spell hits/misses or active spells only misses (only triggers)
2901 else
2902 {
2903 // Fill base damage struct (unitTarget - is real spell target)
2905 procEx |= createProcExtendMask(&damageInfo, missInfo);
2906 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2907 if (canEffectTrigger)
2908 {
2909 DamageInfo dmgInfo(damageInfo, NODAMAGE);
2910 Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2911 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2912
2913 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2914 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2918 }
2919
2920 // Failed Pickpocket, reveal rogue
2922 {
2926 }
2927 }
2928
2929 if (m_caster)
2930 {
2932 {
2935
2936 // Patch 3.0.8: All player spells which cause a creature to become aggressive to you will now also immediately cause the creature to be tapped.
2937 if (effectUnit->IsInCombatWith(m_caster))
2938 {
2939 if (Creature* creature = effectUnit->ToCreature())
2940 {
2941 if (!creature->hasLootRecipient() && m_caster->IsPlayer())
2942 {
2943 creature->SetLootRecipient(m_caster);
2944 }
2945 }
2946 }
2947
2948 // Unsure if there are more spells that are not supposed to stop enemy from
2949 // regenerating HP from food, so for now it stays as an ID.
2950 const uint32 SPELL_PREMEDITATION = 14183;
2951 if (m_spellInfo->Id != SPELL_PREMEDITATION)
2952 {
2953 if (!effectUnit->IsStandState())
2954 {
2956 }
2957 }
2958 }
2959 }
2960
2961 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && m_caster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
2963 {
2964 m_caster->SetInCombatWith(effectUnit);
2965 }
2966
2967 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
2969 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
2970
2971 if (spellHitTarget)
2972 {
2973 //AI functions
2974 if (spellHitTarget->IsCreature())
2975 {
2976 if (spellHitTarget->ToCreature()->IsAIEnabled)
2977 spellHitTarget->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
2978 }
2979
2981 m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
2982
2983 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
2984 DoTriggersOnSpellHit(spellHitTarget, mask);
2985
2986 // if target is fallged for pvp also flag caster if a player
2987 // xinef: do not flag spells with aura bind sight (no special attribute)
2988 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
2990 {
2991 m_caster->ToPlayer()->UpdatePvP(true);
2992 }
2993
2995 }
2996}
@ SPELL_EFFECT_HEALTH_LEECH
Definition: SharedDefines.h:787
@ SPELL_ATTR1_NO_THREAT
Definition: SharedDefines.h:429
@ SPELL_ATTR3_SUPPRESS_CASTER_PROCS
Definition: SharedDefines.h:509
@ SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT
Definition: SharedDefines.h:402
@ SPELL_HIT_TYPE_CRIT
Definition: SharedDefines.h:1536
SpellMissInfo
Definition: SharedDefines.h:1518
@ SPELL_MISS_DODGE
Definition: SharedDefines.h:1522
@ SPELL_MISS_IMMUNE2
Definition: SharedDefines.h:1527
@ SPELL_MISS_RESIST
Definition: SharedDefines.h:1521
@ SPELL_MISS_MISS
Definition: SharedDefines.h:1520
@ SPELL_MISS_BLOCK
Definition: SharedDefines.h:1524
@ SPELL_ATTR4_SUPPRESS_WEAPON_PROCS
Definition: SharedDefines.h:553
@ SPELL_ATTR0_CU_NO_PVP_FLAG
Definition: SpellInfo.h:183
@ SPELL_ATTR0_CU_PICKPOCKET
Definition: SpellInfo.h:186
static const uint32 SPELL_INTERRUPT_NONPLAYER
Definition: Spell.h:269
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:53
@ PROC_EX_NO_OVERHEAL
Definition: SpellMgr.h:213
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
Definition: SpellMgr.h:132
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
Definition: SpellMgr.h:126
@ PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
Definition: SpellMgr.h:129
@ PROC_FLAG_TAKEN_DAMAGE
Definition: SpellMgr.h:137
@ PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
Definition: SpellMgr.h:123
@ NODAMAGE
Definition: Unit.h:252
@ SPELL_DIRECT_DAMAGE
Definition: Unit.h:249
@ HEAL
Definition: Unit.h:251
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition)
Definition: Unit.cpp:15990
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:32
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:27
virtual void SpellHitTarget(Unit *, SpellInfo const *)
Definition: CreatureAI.h:145
virtual void SpellHit(Unit *, SpellInfo const *)
Definition: CreatureAI.h:142
void threatAssist(Unit *victim, float baseThreat, SpellInfo const *threatSpell=nullptr)
Definition: HostileRefMgr.cpp:35
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer=true)
Definition: Creature.cpp:3804
CreatureAI * AI() const
Definition: Creature.h:140
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition: Player.cpp:9945
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition: Player.cpp:7209
void UpdatePvP(bool state, bool _override=false)
Definition: PlayerUpdates.cpp:1483
Definition: Unit.h:330
Definition: Unit.h:373
Definition: Unit.h:489
uint32 m_lastSanctuaryTime
Definition: Unit.h:1913
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition: Unit.cpp:1438
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition: Unit.cpp:6445
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition: Unit.cpp:6278
bool CanProc()
Definition: Unit.h:1430
bool IsPvP() const
Definition: Unit.h:981
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:12447
void SetInCombatWith(Unit *enemy, uint32 duration=0)
Definition: Unit.cpp:13576
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition: Unit.cpp:11239
bool IsStandState() const
Definition: Unit.cpp:16716
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:21034
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:907
int32 GetHealthGain(int32 dVal)
Definition: Unit.cpp:14118
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition: Unit.cpp:12316
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition: Unit.cpp:6310
bool IsAIEnabled
Definition: Unit.h:1919
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition: Unit.h:916
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:12565
void SetStandState(uint8 state)
Definition: Unit.cpp:16722
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5181
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition: Unit.cpp:800
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition: Unit.cpp:1295
ObjectGuid GetUnitTargetGUID() const
Definition: Spell.cpp:216
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition: Spell.cpp:8735
SpellValue const * GetSpellValue()
Definition: Spell.h:585
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition: Spell.cpp:2998
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition: Spell.cpp:3264
uint32 AttributesEx3
Definition: SpellInfo.h:327
bool IsAuraEffectEqual(SpellInfo const *otherSpellInfo) const
Definition: SpellInfo.cpp:1698
bool IsTargetingArea() const
Definition: SpellInfo.cpp:1025
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1242

References SpellNonMeleeDamage::absorb, Creature::AI(), TargetInfo::alive, UnitAI::AttackStart(), SpellInfo::AttributesEx3, AURA_INTERRUPT_FLAG_TALK, SpellNonMeleeDamage::blocked, Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), Unit::CombatStart(), createProcExtendMask(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, Unit::DealDamageMods(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, WorldObject::FindMap(), ObjectAccessor::FindPlayer(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), Unit::getHostileRefMgr(), Unit::GetOwner(), Unit::GetOwnerGUID(), SpellInfo::GetSchoolMask(), GetSpellValue(), getState(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTargetGUID(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Object::IsCreature(), Map::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsInCombat(), Unit::IsInCombatWith(), Object::IsPlayer(), ObjectGuid::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsPvP(), Unit::IsStandState(), SpellInfo::IsTargetingArea(), Creature::LowerPlayerDamageReq(), m_attackType, m_caster, m_damage, m_healing, Unit::m_lastSanctuaryTime, m_needComboPoints, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellAura, m_spellInfo, m_spellSchoolMask, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, TargetInfo::missCondition, NODAMAGE, PrepareScriptHitHandlers(), PROC_EX_CRITICAL_HIT, PROC_EX_NO_OVERHEAL, PROC_EX_NORMAL_HIT, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS, PROC_FLAG_TAKEN_DAMAGE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS, Unit::ProcDamageAndSpell(), TargetInfo::processed, TargetInfo::reflectResult, Unit::RemoveAurasWithInterruptFlags(), Player::RestoreSpellMods(), TargetInfo::scaleAura, Unit::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), Unit::SendSpellNonMeleeReflectLog(), Unit::SetInCombatWith(), Unit::SetLastDamagedTargetGuid(), Unit::SetStandState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR0_CU_PICKPOCKET, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_CASTER_PROCS, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR4_SUPPRESS_WEAPON_PROCS, SPELL_ATTR7_CAN_CAUSE_INTERRUPT, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_DISPEL, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_HEALTH_LEECH, SPELL_HIT_TYPE_CRIT, SPELL_INTERRUPT_NONPLAYER, SPELL_MISS_BLOCK, SPELL_MISS_DODGE, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE2, SPELL_MISS_MISS, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, SPELL_MISS_RESIST, SPELL_STATE_DELAYED, Unit::SpellCriticalHealingBonus(), Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), CreatureAI::SpellHit(), CreatureAI::SpellHitTarget(), TriggeredByAuraSpellData::spellInfo, SpellNonMeleeDamage::target, TargetInfo::targetGUID, HostileRefMgr::threatAssist(), TargetInfo::timeDelay, Object::ToCreature(), Object::ToPlayer(), UNIT_STAND_STATE_STAND, unitTarget, and Player::UpdatePvP().

Referenced by _handle_immediate_phase(), handle_delayed(), and handle_immediate().

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1648{
1649 if (!unitTarget)
1650 return;
1651
1652 Player* player = unitTarget->ToPlayer();
1653 if (!player)
1654 {
1655 return;
1656 }
1657
1658 uint32 newitemid = itemId;
1659
1660 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1661 if (!pProto)
1662 {
1663 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1664 return;
1665 }
1666
1667 uint32 addNumber = damage;
1668
1669 // bg reward have some special in code work
1670 bool SelfCast = true;
1671 switch (m_spellInfo->Id)
1672 {
1677 case SPELL_WS_MARK_TIE:
1680 SelfCast = true;
1681 break;
1683 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1684 addNumber = 3;
1685 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1686 addNumber = 2;
1687 else
1688 addNumber = 1;
1689 SelfCast = true;
1690 break;
1691 }
1692
1693 if (addNumber < 1)
1694 addNumber = 1;
1695 if (addNumber > pProto->GetMaxStackSize())
1696 addNumber = pProto->GetMaxStackSize();
1697
1698 /* == gem perfection handling == */
1699
1700 // the chance of getting a perfect result
1701 float perfectCreateChance = 0.0f;
1702
1703 // the resulting perfect item if successful
1704 uint32 perfectItemType = itemId;
1705
1706 // get perfection capability and chance
1707 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1708 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1709 newitemid = perfectItemType; // the perfect item replaces the regular one
1710
1711 /* == gem perfection handling over == */
1712
1713 /* == profession specialization handling == */
1714
1715 // init items_count to 1, since 1 item will be created regardless of specialization
1716 int32 itemsCount = 1;
1717 float additionalCreateChance = 0.0f;
1718 int32 additionalMaxNum = 0;
1719 // get the chance and maximum number for creating extra items
1720 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1721 {
1722 // roll with this chance till we roll not to create or we create the max num
1723 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1724 ++itemsCount;
1725 }
1726
1727 // really will be created more items
1728 addNumber *= itemsCount;
1729
1730 /* == profession specialization handling over == */
1731
1732 // can the player store the new item?
1733 ItemPosCountVec dest;
1734 uint32 no_space = 0;
1735 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1736 if (msg != EQUIP_ERR_OK)
1737 {
1738 // convert to possible store amount
1740 addNumber -= no_space;
1741 else
1742 {
1743 // if not created by another reason from full inventory or unique items amount limitation
1744 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1745 return;
1746 }
1747 }
1748
1749 if (addNumber)
1750 {
1751 // create the new item and store it
1752 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1753
1754 // was it successful? return error if not
1755 if (!pItem)
1756 {
1757 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1758 return;
1759 }
1760
1761 // set the "Crafted by ..." property of the item
1762 if (pItem->GetTemplate()->HasSignature())
1763 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1764
1765 // send info to the client
1766 player->SendNewItem(pItem, addNumber, true, SelfCast);
1767
1768 sScriptMgr->OnCreateItem(player, pItem, addNumber);
1769
1770 // we succeeded in creating at least one item, so a levelup is possible
1771 if (SelfCast)
1773 }
1774}
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition: SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition: SkillExtraItems.cpp:202
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:64
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
@ SPELL_WS_MARK_WINNER
Definition: Battleground.h:106
@ SPELL_AV_MARK_LOSER
Definition: Battleground.h:110
@ SPELL_WS_MARK_TIE
Definition: Battleground.h:107
@ SPELL_WS_MARK_LOSER
Definition: Battleground.h:105
@ SPELL_AB_MARK_LOSER
Definition: Battleground.h:108
@ SPELL_WG_MARK_WINNER
Definition: Battleground.h:114
@ SPELL_AB_MARK_WINNER
Definition: Battleground.h:109
@ SPELL_AV_MARK_WINNER
Definition: Battleground.h:111
bool HasSignature() const
Definition: ItemTemplate.h:698
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
bool UpdateCraftSkill(uint32 spellid)
Definition: PlayerUpdates.cpp:782
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition: PlayerStorage.cpp:4750
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
Definition: PlayerStorage.cpp:2524

References canCreateExtraItems(), CanCreatePerfectItem(), Player::CanStoreNewItem(), damage, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_INVENTORY_FULL, EQUIP_ERR_ITEM_NOT_FOUND, EQUIP_ERR_OK, Object::GetGUID(), ItemTemplate::GetMaxStackSize(), Item::GetTemplate(), Unit::HasAura(), ItemTemplate::HasSignature(), SpellInfo::Id, ITEM_FIELD_CREATOR, m_spellInfo, NULL_BAG, NULL_SLOT, roll_chance_f(), Player::SendEquipError(), Player::SendNewItem(), Object::SetGuidValue(), sObjectMgr, SPELL_AB_MARK_LOSER, SPELL_AB_MARK_WINNER, SPELL_AV_MARK_LOSER, SPELL_AV_MARK_WINNER, SPELL_WG_MARK_WINNER, SPELL_WS_MARK_LOSER, SPELL_WS_MARK_TIE, SPELL_WS_MARK_WINNER, sScriptMgr, Player::StoreNewItem(), Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

Referenced by SpellScript::CreateItem(), EffectCreateItem(), EffectCreateItem2(), and EffectEnchantItemPerm().

◆ DoSpellHitOnUnit()

SpellMissInfo Spell::DoSpellHitOnUnit ( Unit unit,
uint32  effectMask,
bool  scaleAura 
)
protected
Todo:
: this cause soul transfer bugged
2999{
3000 if (!unit || !effectMask)
3001 return SPELL_MISS_EVADE;
3002
3003 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3004 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
3005 {
3006 return SPELL_MISS_IMMUNE;
3007 }
3008
3009 // disable effects to which unit is immune
3010 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3011 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3012 {
3013 if (effectMask & (1 << effectNumber))
3014 {
3015 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
3016 effectMask &= ~(1 << effectNumber);
3017 // Xinef: Buggs out polymorph
3018 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3019 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3020 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3021 {
3022 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3023 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3024
3025 if (debuff_resist_chance > 0)
3026 if (irand(0,10000) <= (debuff_resist_chance * 100))
3027 {
3028 effectMask &= ~(1 << effectNumber);
3029 returnVal = SPELL_MISS_RESIST;
3030 }
3031 }*/
3032 }
3033 }
3034 if (!effectMask)
3035 return returnVal;
3036
3037 if (unit->IsPlayer())
3038 {
3042 }
3043
3044 if (m_caster->IsPlayer())
3045 {
3048 }
3049
3050 if (m_caster != unit)
3051 {
3052 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3053 // Xinef: Also check evade state
3054 if (m_spellInfo->Speed > 0.0f)
3055 {
3056 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3057 return SPELL_MISS_EVADE;
3058
3060 return SPELL_MISS_EVADE;
3061 }
3062
3063 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3064 {
3066 }
3067 else if (m_caster->IsFriendlyTo(unit))
3068 {
3069 // for delayed spells ignore negative spells (after duel end) for friendly targets
3071 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3072 return SPELL_MISS_EVADE;
3073
3074 // assisting case, healing and resurrection
3076 {
3079 m_caster->ToPlayer()->UpdatePvP(true);
3080 }
3081
3082 // xinef: triggered spells should not prolong combat
3084 {
3085 m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
3086 unit->getHostileRefMgr().threatAssist(m_caster, 0.0f);
3087 }
3088 }
3089 }
3090
3091 uint8 aura_effmask = 0;
3092 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3093 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3094 aura_effmask |= 1 << i;
3095
3096 Unit* originalCaster = GetOriginalCaster();
3097 if (!originalCaster)
3098 originalCaster = m_caster;
3099
3100 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3101 // Xinef: Do not increase diminishing level for self cast
3103 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3105 {
3108
3109 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3110
3111 // Increase Diminishing on unit, current informations for actually casts will use values above
3112 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3114 {
3115 // Do not apply diminish return if caster is NPC
3117 {
3119 }
3120 }
3121 }
3122
3124 {
3126 }
3127
3128 if (aura_effmask)
3129 {
3130 // Select rank for aura with level requirements only in specific cases
3131 // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
3132 SpellInfo const* aurSpellInfo = m_spellInfo;
3133 int32 basePoints[3];
3134 if (scaleAura)
3135 {
3137 ASSERT(aurSpellInfo);
3138 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3139 {
3140 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3141 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3142 {
3143 aurSpellInfo = m_spellInfo;
3144 break;
3145 }
3146 }
3147 }
3148
3149 if (m_originalCaster)
3150 {
3151 bool refresh = false;
3153 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3154 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3155
3156 // xinef: if aura was not refreshed, add proc ex
3157 if (!refresh)
3159
3160 if (m_spellAura)
3161 {
3162 // Prevent aura application if target is banished and immuned
3165 {
3167 return SPELL_MISS_IMMUNE;
3168 }
3169
3170 // Set aura stack amount to desired value
3172 {
3173 if (!refresh)
3175 else
3177 }
3178
3179 // Now Reduce spell duration using data received at spell hit
3180 int32 duration = m_spellAura->GetMaxDuration();
3181 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3182
3183 // Xinef: if unit == caster - test versus original unit if available
3184 float diminishMod = 1.0f;
3185 if (unit == m_caster && m_targets.GetUnitTarget())
3187 else
3188 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3189
3190 // unit is immune to aura if it was diminished to 0 duration
3191 if (diminishMod == 0.0f)
3192 {
3195 return SPELL_MISS_IMMUNE;
3196 bool found = false;
3197 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3198 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3199 found = true;
3200 if (!found)
3201 return SPELL_MISS_IMMUNE;
3202 }
3203 else
3204 {
3205 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3206
3207 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3209 positive = aurApp->IsPositive();
3210
3211 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3212
3213 // xinef: haste affects duration of those spells twice
3216
3217 if (m_spellValue->AuraDuration != 0)
3218 {
3219 if (m_spellAura->GetMaxDuration() != -1)
3220 {
3222 }
3223
3225 }
3226 else if (duration != m_spellAura->GetMaxDuration())
3227 {
3228 m_spellAura->SetMaxDuration(duration);
3229 m_spellAura->SetDuration(duration);
3230 }
3231
3232 // xinef: apply relic cooldown, imo best place to add this
3235
3238 }
3239 }
3240 }
3241 }
3242
3243 int8 sanct_effect = -1;
3244
3245 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3246 {
3247 // handle sanctuary effects after aura apply!
3248 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3249 {
3250 sanct_effect = effectNumber;
3251 continue;
3252 }
3253
3254 if (effectMask & (1 << effectNumber))
3255 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3256 }
3257
3258 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3259 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3260
3261 return SPELL_MISS_NONE;
3262}
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition: DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition: DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition: DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition: DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition: DBCEnums.h:217
@ DIMINISHING_TAUNT
Definition: SharedDefines.h:3276
@ SPELL_EFFECT_SANCTUARY
Definition: SharedDefines.h:857
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition: SharedDefines.h:580
DiminishingReturnsType
Definition: SharedDefines.h:3249
@ DRTYPE_PLAYER
Definition: SharedDefines.h:3251
@ DRTYPE_ALL
Definition: SharedDefines.h:3252
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition: SpellInfo.h:182
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition: SpellMgr.cpp:275
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition: SpellMgr.cpp:58
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:245
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition: SpellDefines.h:43
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition: SpellDefines.h:149
@ SPELL_AURA_PERIODIC_HASTE
Definition: SpellAuraDefines.h:379
@ SPELL_AURA_REFLECT_SPELLS
Definition: SpellAuraDefines.h:91
@ SPELL_AURA_MOD_STEALTH
Definition: SpellAuraDefines.h:79
@ PROC_EX_NO_AURA_REFRESH
Definition: SpellMgr.h:214
@ UNIT_MOD_CAST_SPEED
Definition: UpdateFields.h:137
@ UNIT_STATE_ATTACK_PLAYER
Definition: UnitDefines.h:163
@ UNIT_STATE_ISOLATED
Definition: UnitDefines.h:162
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:230
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition: CreatureData.h:64
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition: CreatureData.h:65
bool isWorldBoss() const
Definition: Creature.h:120
bool IsInEvadeMode() const
Definition: Creature.h:134
uint32 flags_extra
Definition: CreatureData.h:246
float GetFloatValue(uint16 index) const
Definition: Object.cpp:317
static ObjectGuid const Empty
Definition: ObjectGuid.h:120
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:5738
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition: Unit.cpp:15002
void IncrDiminishing(DiminishingGroup group)
Definition: Unit.cpp:15028
uint32 GetCombatTimer() const
Definition: Unit.h:894
bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12827
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17244
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:712
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition: Unit.cpp:15042
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition: Unit.cpp:14868
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition: Unit.h:1262
void SetInCombatState(bool PvP, Unit *enemy=nullptr, uint32 duration=0)
Definition: Unit.cpp:13727
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1234
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5705
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12742
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition: Unit.cpp:12911
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition: Unit.cpp:12896
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10236
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition: Unit.cpp:13872
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.h:1220
Definition: SpellAuras.h:37
int32 GetMaxDuration() const
Definition: SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition: SpellAuras.cpp:995
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition: SpellAuras.cpp:2747
void _RegisterForTargets()
Definition: SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition: SpellAuras.cpp:1021
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint8 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, bool *refresh=nullptr, bool periodicReset=false)
Definition: SpellAuras.cpp:326
void SetDuration(int32 duration, bool withMods=false)
Definition: SpellAuras.cpp:868
const AuraApplication * GetApplicationOfTarget(ObjectGuid guid) const
Definition: SpellAuras.h:183
void SetMaxDuration(int32 duration)
Definition: SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
Definition: SpellAuras.h:279
int32 AuraDuration
Definition: Spell.h:219
uint8 AuraStackAmount
Definition: Spell.h:218
Unit * GetOriginalCaster() const
Definition: Spell.h:576
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2526

References Unit::_IsValidAttackTarget(), Aura::_RegisterForTargets(), ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, Unit::AddSpellCooldown(), Unit::ApplyDiminishingToDuration(), ASSERT, AURA_INTERRUPT_FLAG_HITBYSPELL, SpellValue::AuraDuration, SpellValue::AuraStackAmount, CREATURE_FLAG_EXTRA_ALL_DIMINISH, CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS, DIMINISHING_TAUNT, DRTYPE_ALL, DRTYPE_PLAYER, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, CreatureTemplate::flags_extra, Aura::GetApplicationOfTarget(), SpellInfo::GetAuraRankForLevel(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCombatTimer(), Creature::GetCreatureTemplate(), Unit::GetDiminishing(), GetDiminishingReturnsGroupForSpell(), GetDiminishingReturnsGroupType(), GetDiminishingReturnsLimitDuration(), Object::GetEntry(), Object::GetFloatValue(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetLevel(), Aura::GetMaxDuration(), GetOriginalCaster(), Aura::GetSpellInfo(), Item::GetTemplate(), SpellCastTargets::GetUnitTarget(), HandleEffects(), SpellInfo::HasAttribute(), Unit::HasAuraType(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), Unit::HasUnitFlag(), Unit::HasUnitState(), SpellInfo::Id, Unit::IncrDiminishing(), ItemTemplate::InventoryType, INVTYPE_RELIC, Unit::IsCharmedOwnedByPlayerOrPlayer(), Object::IsCreature(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToDamageOrSchool(), Unit::IsImmunedToSchool(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), Creature::isWorldBoss(), m_caster, m_CastItem, m_damage, m_diminishGroup, m_diminishLevel, m_originalCaster, m_procEx, m_spellAura, m_spellFlags, m_spellInfo, m_spellValue, m_targets, m_triggeredByAuraSpell, MAX_SPELL_EFFECTS, Unit::ModSpellDuration(), Aura::ModStackAmount(), PROC_EX_NO_AURA_REFRESH, Aura::Remove(), Unit::RemoveAurasByType(), Unit::RemoveAurasWithInterruptFlags(), Unit::SetContestedPvP(), Aura::SetDuration(), Unit::SetInCombatState(), Aura::SetMaxDuration(), Aura::SetStackAmount(), Aura::SetTriggeredByAuraSpellInfo(), SpellInfo::Speed, SPELL_ATTR0_CU_DONT_BREAK_STEALTH, SPELL_ATTR0_CU_NO_PVP_FLAG, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_MOD_STEALTH, SPELL_AURA_PERIODIC_HASTE, SPELL_AURA_REFLECT_SPELLS, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_SANCTUARY, SPELL_FLAG_REFLECTED, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_RELIC_COOLDOWN, TriggeredByAuraSpellData::spellInfo, SpellInfo::StackAmount, Player::StartTimedAchievement(), HostileRefMgr::threatAssist(), Object::ToCreature(), Object::ToPlayer(), TRIGGERED_NO_PERIODIC_RESET, Aura::TryRefreshStackOrCreate(), UNIT_FLAG_NON_ATTACKABLE, UNIT_MOD_CAST_SPEED, UNIT_STATE_ATTACK_PLAYER, UNIT_STATE_ISOLATED, unitTarget, Player::UpdateAchievementCriteria(), and Player::UpdatePvP().

Referenced by DoAllEffectOnTarget().

◆ DoTriggersOnSpellHit()

void Spell::DoTriggersOnSpellHit ( Unit unit,
uint8  effMask 
)
protected
Todo:
: move this code to scripts
Todo:
: remove/cleanup this, as this table is not documented and people are doing stupid things with it
3265{
3266 // Apply additional spell effects to target
3268 if (m_preCastSpell)
3269 {
3270 // Paladin immunity shields
3271 if (m_preCastSpell == 61988)
3272 {
3273 // Cast Forbearance
3274 m_caster->CastSpell(unit, 25771, true);
3275 // Cast Avenging Wrath Marker
3276 unit->CastSpell(unit, 61987, true);
3277 }
3278
3279 // Avenging Wrath
3280 if (m_preCastSpell == 61987)
3281 // Cast the serverside immunity shield marker
3282 m_caster->CastSpell(unit, 61988, true);
3283
3284 // Fearie Fire (Feral) - damage
3285 if (m_preCastSpell == 60089)
3286 m_caster->CastSpell(unit, m_preCastSpell, true);
3287 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3288 // Blizz seems to just apply aura without bothering to cast
3290 }
3291
3292 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3293 // this is executed after spell proc spells on target hit
3294 // spells are triggered for each hit spell target
3295 // info confirmed with retail sniffs of permafrost and shadow weaving
3296 if (!m_hitTriggerSpells.empty())
3297 {
3298 int _duration = 0;
3299 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3300 {
3301 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3302 {
3303 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3304 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3305
3306 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3307 // set duration of current aura to the triggered spell
3308 if (i->triggeredSpell->GetDuration() == -1)
3309 {
3310 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3311 {
3312 // get duration from aura-only once
3313 if (!_duration)
3314 {
3315 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3316 _duration = aur ? aur->GetDuration() : -1;
3317 }
3318 triggeredAur->SetDuration(_duration);
3319 }
3320 }
3321 }
3322 }
3323 }
3324
3325 // trigger linked auras remove/apply
3327 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3328 {
3329 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3330 if (*i < 0)
3331 {
3332 unit->RemoveAurasDueToSpell(-(*i));
3333 }
3334 else
3335 {
3336 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3337 }
3338 }
3339}
bool roll_chance_i(int chance)
Definition: Random.h:59
@ SPELL_LINK_HIT
Definition: SpellMgr.h:97
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5581
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:18859
int32 GetDuration() const
Definition: SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition: Spell.h:756

References Unit::AddAura(), CanExecuteTriggersOnHit(), Unit::CastSpell(), Unit::GetAura(), Aura::GetDuration(), Object::GetGUID(), SpellInfo::Id, LOG_DEBUG, m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_LINK_HIT, and sSpellMgr.

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4256{
4258 return;
4259
4260 if (!gameObjTarget)
4261 return;
4262
4263 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4264 switch (action)
4265 {
4266 case GameObjectActions::AnimateCustom0:
4267 case GameObjectActions::AnimateCustom1:
4268 case GameObjectActions::AnimateCustom2:
4269 case GameObjectActions::AnimateCustom3:
4270 gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
4271 break;
4272 case GameObjectActions::Disturb: // What's the difference with Open?
4273 case GameObjectActions::Open:
4274 if (Unit* unitCaster = m_caster->ToUnit())
4275 gameObjTarget->Use(unitCaster);
4276 break;
4277 case GameObjectActions::OpenAndUnlock:
4278 if (Unit* unitCaster = m_caster->ToUnit())
4279 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4280 [[fallthrough]];
4281 case GameObjectActions::Unlock:
4282 case GameObjectActions::Lock:
4283 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
4284 break;
4285 case GameObjectActions::Close:
4286 case GameObjectActions::Rebuild:
4288 break;
4289 case GameObjectActions::Despawn:
4291 break;
4292 case GameObjectActions::MakeInert:
4293 case GameObjectActions::MakeActive:
4294 gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
4295 break;
4296 case GameObjectActions::CloseAndLock:
4299 break;
4300 case GameObjectActions::Destroy:
4301 if (Unit* unitCaster = m_caster->ToUnit())
4302 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4303 break;
4304 case GameObjectActions::UseArtKit0:
4305 case GameObjectActions::UseArtKit1:
4306 case GameObjectActions::UseArtKit2:
4307 case GameObjectActions::UseArtKit3:
4308 {
4309 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4310
4311 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4312
4313 uint32 artKitValue = 0;
4314 if (templateAddon)
4315 artKitValue = templateAddon->artKits[artKitIndex];
4316
4317 if (artKitValue == 0)
4318 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4319 else
4320 gameObjTarget->SetGoArtKit(artKitValue);
4321
4322 break;
4323 }
4324 case GameObjectActions::None:
4325 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4326 break;
4327 default:
4328 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4329 break;
4330 }
4331}
#define LOG_FATAL(filterType__,...)
Definition: Log.h:153
@ GO_FLAG_NOT_SELECTABLE
Definition: SharedDefines.h:1607
@ GO_FLAG_LOCKED
Definition: SharedDefines.h:1604
GameObjectActions
Definition: GameObject.h:76
@ GAMEOBJECT_FLAGS
Definition: UpdateFields.h:399
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition: GameObject.cpp:1429
void SetGoArtKit(uint8 artkit)
Definition: GameObject.cpp:1443
void SendCustomAnim(uint32 anim)
Definition: GameObject.cpp:2150
void ResetDoorOrButton()
Definition: GameObject.cpp:1419
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition: GameObject.cpp:933
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition: GameObject.cpp:912
void Use(Unit *user)
Definition: GameObject.cpp:1479
Definition: GameObjectData.h:664
std::array< uint32, 4 > artKits
Definition: GameObjectData.h:670
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:899

References Object::ApplyModFlag(), GameObjectTemplateAddon::artKits, GameObject::DespawnOrUnsummon(), effectHandleMode, SpellInfo::Effects, GAMEOBJECT_FLAGS, gameObjTarget, Object::GetEntry(), GameObject::GetTemplateAddon(), GO_FLAG_LOCKED, GO_FLAG_NOT_SELECTABLE, SpellInfo::Id, LOG_ERROR, LOG_FATAL, m_caster, m_spellInfo, GameObject::ResetDoorOrButton(), GameObject::SendCustomAnim(), Object::SetFlag(), GameObject::SetGoArtKit(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToUnit(), GameObject::Use(), and GameObject::UseDoorOrButton().

◆ EffectActivateRune()

void Spell::EffectActivateRune ( SpellEffIndex  effIndex)
5770{
5772 return;
5773
5774 if (!m_caster->IsPlayer())
5775 return;
5776
5777 Player* player = m_caster->ToPlayer();
5778
5780 return;
5781
5782 // needed later
5784
5785 uint32 count = damage;
5786 if (count == 0) count = 1;
5787 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5788 {
5789 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5790 {
5791 if (m_spellInfo->Id == 45529)
5792 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5793 continue;
5794 player->SetRuneCooldown(j, 0);
5795 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5796 --count;
5797 }
5798 }
5799
5800 // Blood Tap
5801 if (m_spellInfo->Id == 45529 && count > 0)
5802 {
5803 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5804 {
5805 // Check if both runes are on cd as that is the only time when this needs to come into effect
5806 if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
5807 {
5808 // Should always update the rune with the lowest cd
5809 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5810 l++;
5811 player->SetRuneCooldown(l, 0);
5812 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5813 --count;
5814 }
5815 else
5816 break;
5817 }
5818 }
5819
5820 // Empower rune weapon
5821 if (m_spellInfo->Id == 47568)
5822 {
5823 // Need to do this just once
5824 if (effIndex != 0)
5825 return;
5826
5827 for (uint32 i = 0; i < MAX_RUNES; ++i)
5828 {
5829 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5830 {
5831 player->SetRuneCooldown(i, 0);
5832 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5833 }
5834 }
5835 }
5836
5837 // is needed to push through to the client that the rune is active
5838 //player->ResyncRunes(MAX_RUNES);
5839 m_caster->CastSpell(m_caster, 47804, true);
5840}
@ RUNE_FROST
Definition: Player.h:411
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition: Player.h:2499
uint8 GetRunesState() const
Definition: Player.h:2488
void SetGracePeriod(uint8 index, uint32 period)
Definition: Player.h:2500
RuneType GetBaseRune(uint8 index) const
Definition: Player.h:2489

References Unit::CastSpell(), CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, damage, effectHandleMode, SpellInfo::Effects, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneCooldown(), Player::GetRunesState(), SpellInfo::Id, Player::IsClass(), Unit::IsInCombat(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, RUNE_DEATH, RUNE_FROST, Player::SetGracePeriod(), Player::SetRuneCooldown(), SPELL_EFFECT_HANDLE_LAUNCH, and Object::ToPlayer().

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6145{
6147 return;
6148
6149 if (!unitTarget)
6150 return;
6151
6152 if (Player* player = unitTarget->ToPlayer())
6153 {
6154 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6155 }
6156}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4093{
4095 {
4096 return;
4097 }
4098
4099 if (!unitTarget || damage <= 0)
4100 {
4101 return;
4102 }
4103
4105}
void AddComboPointGain(Unit *target, int8 amount)
Definition: Spell.h:532

References AddComboPointGain(), damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddExtraAttacks()

void Spell::EffectAddExtraAttacks ( SpellEffIndex  effIndex)
4675{
4677 {
4678 return;
4679 }
4680
4681 if (!unitTarget || !unitTarget->IsAlive())
4682 {
4683 return;
4684 }
4685
4687
4689}
void AddExtraAttacks(uint32 count)
Definition: Unit.cpp:2765
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition: Spell.cpp:5117

References Unit::AddExtraAttacks(), damage, effectHandleMode, ExecuteLogEffectExtraAttacks(), Unit::IsAlive(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2714{
2716 return;
2717
2718 if (!m_caster->IsPlayer())
2719 return;
2720
2721 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2722 int32 duration = m_spellInfo->GetDuration();
2723 // Caster not in world, might be spell triggered from aura removal
2724 if (!m_caster->IsInWorld())
2725 return;
2726
2727 // Remove old farsight if exist
2728 bool updateViewerVisibility = m_caster->RemoveDynObject(m_spellInfo->Id);
2729
2730 DynamicObject* dynObj = new DynamicObject(true);
2731 if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
2732 {
2733 delete dynObj;
2734 return;
2735 }
2736
2737 dynObj->SetDuration(duration);
2738 dynObj->SetCasterViewpoint(updateViewerVisibility);
2739}
@ DYNAMIC_OBJECT_FARSIGHT_FOCUS
Definition: DynamicObject.h:31
void SetDuration(int32 newDuration)
Definition: DynamicObject.cpp:203
void SetCasterViewpoint(bool updateViewerVisibility)
Definition: DynamicObject.cpp:231
bool CreateDynamicObject(ObjectGuid::LowType guidlow, Unit *caster, uint32 spellId, Position const &pos, float radius, DynamicObjectType type)
Definition: DynamicObject.cpp:97
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:636

References DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_FARSIGHT_FOCUS, effectHandleMode, SpellInfo::Effects, Map::GenerateLowGuid(), SpellInfo::GetDuration(), WorldObject::GetMap(), SpellInfo::Id, Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::RemoveDynObject(), DynamicObject::SetCasterViewpoint(), DynamicObject::SetDuration(), and SPELL_EFFECT_HANDLE_HIT.

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2784{
2786 return;
2787
2788 if (!unitTarget->IsPlayer())
2789 return;
2790
2791 // not scale value for item based reward (/10 value expected)
2792 if (m_CastItem)
2793 {
2794 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2795 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2797 return;
2798 }
2799
2800 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2801 if (damage <= 50)
2802 {
2804 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2805 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2806 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2807 }
2808 else
2809 {
2810 //maybe we have correct honor_gain in damage already
2811 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2812 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2814 }
2815}
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:38
std::string ToString() const
Definition: ObjectGuid.cpp:47
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition: Player.cpp:6072

References damage, effectHandleMode, Object::GetEntry(), Object::GetGUID(), Unit::GetLevel(), Acore::Honor::hk_honor_at_level(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_CastItem, m_spellInfo, Player::RewardHonor(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectApplyAreaAura()

void Spell::EffectApplyAreaAura ( SpellEffIndex  effIndex)
1320{
1322 return;
1323
1324 if (!m_spellAura || !unitTarget)
1325 return;
1328}
WorldObject * GetOwner() const
Definition: SpellAuras.h:107
void _ApplyEffectForTargets(uint8 effIndex)
Definition: SpellAuras.cpp:735

References Aura::_ApplyEffectForTargets(), ASSERT, effectHandleMode, Aura::GetOwner(), m_spellAura, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectApplyAura()

void Spell::EffectApplyAura ( SpellEffIndex  effIndex)

◆ EffectApplyGlyph()

void Spell::EffectApplyGlyph ( SpellEffIndex  effIndex)
4334{
4336 return;
4337
4339 return;
4340
4341 Player* player = m_caster->ToPlayer();
4342
4343 // glyph sockets level requirement
4344 uint8 minLevel = 0;
4345 switch (m_glyphIndex)
4346 {
4347 case 0:
4348 case 1:
4349 minLevel = 15;
4350 break;
4351 case 2:
4352 minLevel = 50;
4353 break;
4354 case 3:
4355 minLevel = 30;
4356 break;
4357 case 4:
4358 minLevel = 70;
4359 break;
4360 case 5:
4361 minLevel = 80;
4362 break;
4363 }
4364 if (minLevel && m_caster->GetLevel() < minLevel)
4365 {
4367 return;
4368 }
4369
4370 // apply new one
4371 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4372 {
4373 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4374 {
4375 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4376 {
4377 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4378 {
4380 return; // glyph slot mismatch
4381 }
4382 }
4383
4384 // remove old glyph aura
4385 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4386 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4387 {
4388 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4389
4390 // Removed any triggered auras
4391 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4392 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4393 {
4394 Aura* aura = iter->second;
4395 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4396 {
4397 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4398 {
4399 player->RemoveOwnedAura(iter);
4400 continue;
4401 }
4402 }
4403 ++iter;
4404 }
4405
4406 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4407 }
4408
4409 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4411 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4412 player->SendTalentsInfoData(false);
4413 }
4414 }
4415}
#define MAX_GLYPH_SLOT_INDEX
Definition: SharedDefines.h:676
@ SPELL_FAILED_GLYPH_SOCKET_LOCKED
Definition: SharedDefines.h:1126
@ SPELL_FAILED_INVALID_GLYPH
Definition: SharedDefines.h:1124
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:147
DBCStorage< GlyphSlotEntry > sGlyphSlotStore(GlyphSlotfmt)
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14429
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:3027
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1753
uint32 GetGlyphSlot(uint8 slot) const
Definition: Player.h:1744
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1745
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4705
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:635
AuraMap & GetOwnedAuras()
Definition: Unit.h:1294
bool PlayerLoading() const
Definition: WorldSession.h:337
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition: SpellAuras.cpp:2761
Definition: DBCStructure.h:1028

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, Player::GetGlyph(), Player::GetGlyphSlot(), Unit::GetLevel(), Unit::GetOwnedAuras(), Player::GetSession(), Aura::GetTriggeredByAuraSpellInfo(), Object::IsPlayer(), m_caster, m_glyphIndex, m_spellInfo, MAX_GLYPH_SLOT_INDEX, WorldSession::PlayerLoading(), Unit::RemoveAurasDueToSpell(), Unit::RemoveOwnedAura(), SendCastResult(), Player::SendLearnPacket(), Player::SendTalentsInfoData(), Player::SetGlyph(), sGlyphPropertiesStore, sGlyphSlotStore, SPELL_EFFECT_HANDLE_HIT, SPELL_FAILED_GLYPH_SOCKET_LOCKED, SPELL_FAILED_INVALID_GLYPH, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, and TRIGGERED_IGNORE_SHAPESHIFT.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6278{
6280 return;
6281
6282 if (!unitTarget)
6283 return;
6284
6285 Player* player = unitTarget->ToPlayer();
6286 if (!player)
6287 {
6288 return;
6289 }
6290
6291 WorldLocation homeLoc;
6292 uint32 areaId = player->GetAreaId();
6293
6294 if (m_spellInfo->Effects[effIndex].MiscValue)
6295 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6296
6297 if (m_targets.HasDst())
6298 homeLoc.WorldRelocate(*destTarget);
6299 else
6300 {
6301 homeLoc = player->GetWorldLocation();
6302 }
6303
6304 player->SetHomebind(homeLoc, areaId);
6305
6306 // binding
6307 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6308 data << float(homeLoc.GetPositionX());
6309 data << float(homeLoc.GetPositionY());
6310 data << float(homeLoc.GetPositionZ());
6311 data << uint32(homeLoc.GetMapId());
6312 data << uint32(areaId);
6313 player->SendDirectMessage(&data);
6314
6315 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6316 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6317 // zone update
6318 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6319 data << m_caster->GetGUID();
6320 data << uint32(areaId);
6321 player->SendDirectMessage(&data);
6322}
@ SMSG_BINDPOINTUPDATE
Definition: Opcodes.h:371
@ SMSG_PLAYERBOUND
Definition: Opcodes.h:374
Definition: Position.h:250
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:258
void GetWorldLocation(uint32 &mapId, float &x, float &y) const
Definition: Position.h:280
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:5700
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition: PlayerStorage.cpp:4896

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetAreaId(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), WorldLocation::GetWorldLocation(), SpellCastTargets::HasDst(), WorldPacket::Initialize(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, Player::SendDirectMessage(), Player::SetHomebind(), SMSG_BINDPOINTUPDATE, SMSG_PLAYERBOUND, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4701{
4703 return;
4704
4705 if (m_caster->IsPlayer())
4706 m_caster->ToPlayer()->SetCanBlock(true);
4707}
void SetCanBlock(bool value)
Definition: Player.cpp:13144

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanBlock(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectCastButtons()

void Spell::EffectCastButtons ( SpellEffIndex  effIndex)

Action button data is unverified when it's set so it can be "hacked" to contain invalid spells, so filter here.

6205{
6207 return;
6208
6209 if (!m_caster->IsPlayer())
6210 return;
6211
6212 Player* p_caster = m_caster->ToPlayer();
6213 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6214 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6215
6216 for (; n_buttons; --n_buttons, ++button_id)
6217 {
6218 ActionButton const* ab = p_caster->GetActionButton(button_id);
6219 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6220 continue;
6221
6224 uint32 spell_id = ab->GetAction();
6225 if (!spell_id)
6226 continue;
6227
6228 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6229 if (!spellInfo)
6230 continue;
6231
6232 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6233 continue;
6234
6236 continue;
6237
6238 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6239 if (m_caster->GetPower(POWER_MANA) < cost)
6240 continue;
6241
6243 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6244 }
6245}
@ SPELL_ATTR7_CAN_BE_MULTI_CAST
Definition: SharedDefines.h:646
@ ACTION_BUTTON_SPELL
Definition: Player.h:229
Definition: Player.h:253
uint32 GetAction() const
Definition: Player.h:261
ActionButtonType GetType() const
Definition: Player.h:260
ActionButton const * GetActionButton(uint8 button)
Definition: Player.cpp:5646
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3867

References ACTION_BUTTON_SPELL, SpellInfo::CalcPowerCost(), Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, ActionButton::GetAction(), Player::GetActionButton(), Unit::GetPower(), SpellInfo::GetSchoolMask(), ActionButton::GetType(), SpellInfo::HasAttribute(), Player::HasSpell(), Player::HasSpellCooldown(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_MANA, SPELL_ATTR7_CAN_BE_MULTI_CAST, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and TRIGGERED_IGNORE_GCD.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
4920{
4922 {
4923 if (!unitTarget)
4924 return;
4925
4926 ObjectGuid targetGUID = ObjectGuid::Empty;
4927 Player* player = m_caster->ToPlayer();
4928 if (player)
4929 {
4930 // charge changes fall time
4932
4934 {
4935 targetGUID = unitTarget->GetGUID();
4936 }
4937 }
4938
4939 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4940 // Spell is not using explicit target - no generated path
4941 if (!m_preGeneratedPath)
4942 {
4944 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4945 }
4946 else
4947 {
4948 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4949 }
4950
4951 if (player)
4952 {
4953 sScriptMgr->AnticheatSetUnderACKmount(player);
4954 }
4955 }
4956}
@ EVENT_CHARGE
Definition: SharedDefines.h:3311
#define SPEED_CHARGE
Definition: MotionMaster.h:109
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition: Object.cpp:2823
Definition: Position.h:27
float m_positionZ
Definition: Position.h:57
float GetRelativeAngle(const Position *pos) const
Definition: Position.h:196
float m_positionX
Definition: Position.h:55
float m_positionY
Definition: Position.h:56
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2319
MotionMaster * GetMotionMaster()
Definition: Unit.h:1622
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, const Movement::PointsArray *path=nullptr, bool generatePath=false, float orientation=0.0f, ObjectGuid targetGUID=ObjectGuid::Empty)
The unit will charge the target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:670

References effectHandleMode, ObjectGuid::Empty, EVENT_CHARGE, Unit::GetCombatReach(), WorldObject::GetFirstCollisionPosition(), GameTime::GetGameTime(), Object::GetGUID(), Unit::GetMotionMaster(), Position::GetPositionZ(), Position::GetRelativeAngle(), Unit::GetTarget(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), m_caster, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_preGeneratedPath, m_spellInfo, MotionMaster::MoveCharge(), Player::SetFallInformation(), SpellInfo::Speed, SPEED_CHARGE, SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectChargeDest()

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1777{
1779 return;
1780
1781 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1782 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1783}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5145
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition: SpellEffects.cpp:1647

References DoCreateItem(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectCreateItem(), m_spellInfo, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectCreateItem2()

void Spell::EffectCreateItem2 ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1786{
1788 return;
1789
1790 if (!unitTarget)
1791 return;
1792
1793 Player* player = unitTarget->ToPlayer();
1794 if (!player)
1795 {
1796 return;
1797 }
1798
1799 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1800
1801 if (itemId)
1802 DoCreateItem(effIndex, itemId);
1803
1804 // special case: fake item replaced by generate using spell_loot_template
1806 {
1807 if (itemId)
1808 {
1809 if (!player->HasItemCount(itemId))
1810 return;
1811
1812 // remove reagent
1813 uint32 count = 1;
1814 player->DestroyItemCount(itemId, count, true);
1815
1816 // create some random items
1818 }
1819 else
1820 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1821 }
1823}
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false)
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const &store, bool broadcast=false)
Definition: Player.cpp:13499
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition: PlayerStorage.cpp:3121
bool IsLootCrafting() const
Definition: SpellInfo.cpp:925

References Player::AutoStoreLoot(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Player::HasItemCount(), SpellInfo::Id, SpellInfo::IsLootCrafting(), LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateRandomItem()

void Spell::EffectCreateRandomItem ( SpellEffIndex  effIndex)
Todo:
: ExecuteLogEffectCreateItem(i, m_spellInfo->Effects[i].ItemType);
1826{
1828 return;
1829
1830 if (!unitTarget)
1831 return;
1832
1833 Player* player = unitTarget->ToPlayer();
1834 if (!player)
1835 {
1836 return;
1837 }
1838
1839 // create some random items
1842}

References Player::AutoStoreLoot(), effectHandleMode, SpellInfo::Id, LootTemplates_Spell, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5843{
5845 return;
5846
5848 return;
5849
5850 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5851 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5852 if (!pet)
5853 return;
5854
5855 // add to world
5856 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5857
5858 // unitTarget has pet now
5859 unitTarget->SetMinion(pet, true);
5860
5861 pet->InitTalentForLevel();
5862
5863 if (unitTarget->IsPlayer())
5864 {
5867 }
5868}
@ CLASS_HUNTER
Definition: SharedDefines.h:143
void InitTalentForLevel()
Definition: Pet.cpp:2225
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:507
void PetSpellInitialize()
Definition: Player.cpp:9478
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:10680
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition: Unit.cpp:17347
bool AddToMap(T *, bool checkTransport=false)
Definition: Map.cpp:558

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), effectHandleMode, SpellInfo::Effects, WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsPlayer(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), and unitTarget.

◆ EffectDestroyAllTotems()

void Spell::EffectDestroyAllTotems ( SpellEffIndex  effIndex)
5254{
5256 return;
5257
5258 int32 mana = 0;
5259 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
5260 {
5261 if (!m_caster->m_SummonSlot[slot])
5262 continue;
5263
5265 if (totem && totem->IsTotem())
5266 {
5267 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5268 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5269 if (spellInfo)
5270 {
5271 mana += spellInfo->ManaCost;
5273 }
5274 totem->ToTotem()->UnSummon();
5275 }
5276 }
5277 ApplyPct(mana, damage);
5278 if (mana)
5279 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5280}
T ApplyPct(T &base, U pct)
Definition: Util.h:73
@ UNIT_CREATED_BY_SPELL
Definition: UpdateFields.h:138
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:597
#define MAX_TOTEM_SLOT
Definition: Unit.h:598
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:122
Totem * ToTotem()
Definition: Unit.h:695
SpellCastResult CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1224
uint32 GetCreateMana() const
Definition: Unit.h:1070
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:1898
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3317
uint32 ManaCostPercentage
Definition: SpellInfo.h:367
uint32 ManaCost
Definition: SpellInfo.h:363

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), Unit::IsTotem(), m_caster, Unit::m_SummonSlot, SpellInfo::ManaCost, SpellInfo::ManaCostPercentage, MAX_TOTEM_SLOT, SPELL_EFFECT_HANDLE_HIT, sSpellMgr, SUMMON_SLOT_TOTEM, Unit::ToTotem(), UNIT_CREATED_BY_SPELL, and Totem::UnSummon().

◆ EffectDiscoverTaxi()

void Spell::EffectDiscoverTaxi ( SpellEffIndex  effIndex)
5871{
5873 return;
5874
5875 if (!unitTarget)
5876 return;
5877
5878 Player* player = unitTarget->ToPlayer();
5879 if (!player)
5880 {
5881 return;
5882 }
5883
5884 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5885 if (sTaxiNodesStore.LookupEntry(nodeid))
5886 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5887}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition: TaxiHandler.cpp:151

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4471{
4473 return;
4474
4476 return;
4477
4478 if (Player* caster = m_caster->ToPlayer())
4479 {
4480 caster->UpdateCraftSkill(m_spellInfo->Id);
4481 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4482 }
4483
4484 // item will be removed at disenchanting end
4485}
@ LOOT_DISENCHANTING
Definition: LootMgr.h:83

References ItemTemplate::DisenchantID, effectHandleMode, Object::GetGUID(), Item::GetTemplate(), SpellInfo::Id, itemTarget, LOOT_DISENCHANTING, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4557{
4559 return;
4560
4561 if (!unitTarget || !unitTarget->IsPet())
4562 return;
4563
4564 Pet* pet = unitTarget->ToPet();
4565
4566 ExecuteLogEffectUnsummonObject(effIndex, pet);
4568}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:884
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5163

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

void Spell::EffectDispel ( SpellEffIndex  effIndex)
2563{
2565 return;
2566
2567 if (!unitTarget)
2568 return;
2569
2570 // Create dispel mask by dispel type
2571 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2572 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2573
2574 DispelChargesList dispel_list;
2575 unitTarget->GetDispellableAuraList(m_caster, dispelMask, dispel_list, m_spellInfo);
2576 if (dispel_list.empty())
2577 return;
2578
2579 // Ok if exist some buffs for dispel try dispel it
2580 uint32 failCount = 0;
2581 DispelChargesList success_list;
2582 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2583 // dispel N = damage buffs (or while exist buffs for dispel)
2584 for (int32 count = 0; count < damage && !dispel_list.empty();)
2585 {
2586 // Random select buff for dispel
2587 DispelChargesList::iterator itr = dispel_list.begin();
2588 std::advance(itr, urand(0, dispel_list.size() - 1));
2589
2590 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
2591 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2592 if (!chance)
2593 {
2594 dispel_list.erase(itr);
2595 continue;
2596 }
2597 else
2598 {
2599 if (roll_chance_i(chance))
2600 {
2601 bool alreadyListed = false;
2602 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2603 {
2604 if (successItr->first->GetId() == itr->first->GetId())
2605 {
2606 ++successItr->second;
2607 alreadyListed = true;
2608 }
2609 }
2610 if (!alreadyListed)
2611 success_list.push_back(std::make_pair(itr->first, 1));
2612 --itr->second;
2613 if (itr->second <= 0)
2614 dispel_list.erase(itr);
2615 }
2616 else
2617 {
2618 if (!failCount)
2619 {
2620 // Failed to dispell
2621 dataFail << m_caster->GetGUID(); // Caster GUID
2622 dataFail << unitTarget->GetGUID(); // Victim GUID
2623 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2624 }
2625 ++failCount;
2626 dataFail << uint32(itr->first->GetId()); // Spell Id
2627 }
2628 ++count;
2629 }
2630 }
2631
2632 if (failCount)
2633 m_caster->SendMessageToSet(&dataFail, true);
2634
2635 // put in combat
2638
2639 if (success_list.empty())
2640 return;
2641
2642 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2643 // Send packet header
2644 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2645 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
2646 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2647 dataSuccess << uint8(0); // not used
2648 dataSuccess << uint32(success_list.size()); // count
2649 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2650 {
2651 // Send dispelled spell info
2652 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2653 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2654 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), m_caster, itr->second);
2655 }
2656 m_caster->SendMessageToSet(&dataSuccess, true);
2657
2658 // On success dispel
2659 // Devour Magic
2661 {
2662 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2663 m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true);
2664 // Glyph of Felhunter
2665 if (Unit* owner = m_caster->GetOwner())
2666 if (owner->GetAura(56249))
2667 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2668 }
2669}
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ SPELLFAMILY_WARLOCK
Definition: SharedDefines.h:3533
@ SPELLCATEGORY_DEVOUR_MAGIC
Definition: SpellMgr.h:40
@ SMSG_DISPEL_FAILED
Definition: Opcodes.h:640
@ SMSG_SPELLDISPELLOG
Definition: Opcodes.h:665
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition: Unit.cpp:5605
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition: Unit.cpp:4942
uint32 GetCategory() const
Definition: SpellInfo.cpp:871

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::getHostileRefMgr(), Unit::GetOwner(), Object::GetPackGUID(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, HostileRefMgr::threatAssist(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5159{
5161 return;
5162
5163 if (!unitTarget)
5164 return;
5165
5166 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5167
5168 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5169
5170 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5171 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5172 {
5173 Aura* aura = itr->second;
5175 continue;
5177 {
5178 if ((aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1 << mechanic)))
5179 {
5180 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5181
5182 // spell only removes 1 bleed effect do not continue
5183 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5184 {
5185 break;
5186 }
5187 }
5188 }
5189 }
5190
5191 for (; dispel_list.size(); dispel_list.pop())
5192 {
5193 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5194 }
5195
5196 // put in combat
5199}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition: SpellAuraDefines.h:394
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4776
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:105
uint32 GetId() const
Definition: SpellAuras.cpp:466
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition: SpellAuras.cpp:1182

References AURA_REMOVE_BY_ENEMY_SPELL, Aura::CalcDispelChance(), effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Aura::GetApplicationOfTarget(), Aura::GetCasterGUID(), Object::GetGUID(), Unit::getHostileRefMgr(), Aura::GetId(), Unit::GetOwnedAuras(), Aura::GetSpellInfo(), Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAura(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, HostileRefMgr::threatAssist(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2686{
2688 return;
2689
2690 // Check for possible target
2691 if (!unitTarget || unitTarget->IsEngaged())
2692 return;
2693
2694 // target must be OK to do this
2696 return;
2697
2700}
@ UNIT_STATE_CONFUSED
Definition: UnitDefines.h:160
@ UNIT_STATE_FLEEING
Definition: UnitDefines.h:156
@ UNIT_STATE_STUNNED
Definition: UnitDefines.h:152
float GetAngle(const Position *pos) const
Definition: Position.cpp:78
void SetFacingTo(float ori)
Definition: Unit.cpp:20523
bool IsEngaged() const
Definition: Unit.h:881
void MoveDistract(uint32 time)
Enable the target's distract movement. Doesn't work with UNIT_FLAG_DISABLE_MOVE and if the unit has M...
Definition: MotionMaster.cpp:798

References damage, destTarget, effectHandleMode, Position::GetAngle(), Unit::GetMotionMaster(), Unit::HasUnitState(), IN_MILLISECONDS, Unit::IsEngaged(), MotionMaster::MoveDistract(), Unit::SetFacingTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_CONFUSED, UNIT_STATE_FLEEING, UNIT_STATE_STUNNED, and unitTarget.

◆ EffectDualWield()

void Spell::EffectDualWield ( SpellEffIndex  effIndex)
2672{
2674 return;
2675
2677}
virtual void SetCanDualWield(bool value)
Definition: Unit.h:924

References effectHandleMode, Unit::SetCanDualWield(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4108{
4110 return;
4111
4112 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4113 return;
4114
4115 Player* caster = m_caster->ToPlayer();
4116 Player* target = unitTarget->ToPlayer();
4117
4118 // caster or target already have requested duel
4119 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4120 return;
4121
4122 // Players can only fight a duel in zones with this flag
4123 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4124 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4125 {
4126 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4127 return;
4128 }
4129
4130 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4131 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4132 {
4133 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4134 return;
4135 }
4136
4137 //CREATE DUEL FLAG OBJECT
4138 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4139 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4140
4141 Map* map = m_caster->GetMap();
4142 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4143 map, m_caster->GetPhaseMask(),
4147 m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4148 {
4149 delete pGameObj;
4150 return;
4151 }
4152
4155 int32 duration = m_spellInfo->GetDuration();
4156 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4157 pGameObj->SetSpellId(m_spellInfo->Id);
4158
4159 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4160
4161 m_caster->AddGameObject(pGameObj);
4162 map->AddToMap(pGameObj, true);
4163 //END
4164
4165 // Send request
4166 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4167 data << pGameObj->GetGUID();
4168 data << caster->GetGUID();
4169 caster->GetSession()->SendPacket(&data);
4170 target->GetSession()->SendPacket(&data);
4171
4172 // create duel-info
4173 bool isMounted = (GetSpellInfo()->Id == 62875);
4174 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4175 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4176
4177 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4178 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4179
4180 sScriptMgr->OnPlayerDuelRequest(target, caster);
4181}
@ AREA_FLAG_ALLOW_DUELS
Definition: DBCEnums.h:240
@ SPELL_FAILED_NO_DUELING
Definition: SharedDefines.h:1028
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ GAMEOBJECT_LEVEL
Definition: UpdateFields.h:403
@ GAMEOBJECT_FACTION
Definition: UpdateFields.h:402
@ SMSG_DUEL_REQUESTED
Definition: Opcodes.h:389
virtual bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const &rotation, uint32 animprogress, GOState go_state, uint32 artKit=0)
Definition: GameObject.cpp:254
void SetRespawnTime(int32 respawn)
Definition: GameObject.cpp:1303
void SetSpellId(uint32 id)
Definition: GameObject.h:176
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
uint32 GetPhaseMask() const
Definition: Object.h:446
float GetOrientation() const
Definition: Position.h:119
PlayerSocial * GetSocial()
Definition: Player.h:1141
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193
Definition: Transport.h:112
uint32 GetFaction() const
Definition: Unit.h:808
void AddGameObject(GameObject *gameObj)
Definition: Unit.cpp:6179
void SendPacket(WorldPacket const *packet)
Send a packet to the client.
Definition: WorldSession.cpp:214
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition: Spell.cpp:5157
uint32 flags
Definition: DBCStructure.h:523

References Unit::AddGameObject(), Map::AddToMap(), AREA_FLAG_ALLOW_DUELS, GameObject::Create(), Player::duel, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), AreaTableEntry::flags, GAMEOBJECT_FACTION, GAMEOBJECT_LEVEL, Map::GenerateLowGuid(), WorldObject::GetAreaId(), SpellInfo::GetDuration(), Unit::GetFaction(), Object::GetGUID(), Unit::GetLevel(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Player::GetSession(), Player::GetSocial(), GetSpellInfo(), GO_STATE_READY, PlayerSocial::HasIgnore(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), m_caster, m_spellInfo, PLAYER_DUEL_ARBITER, sAreaTableStore, SendCastResult(), WorldSession::SendPacket(), Object::SetGuidValue(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), Object::SetUInt32Value(), SMSG_DUEL_REQUESTED, sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_NO_DUELING, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
663{
665 return;
666
668 return;
669
670 // selection by spell family
672 {
674 {
675 switch (m_spellInfo->Id)
676 {
677 // Trial of the Champion, Trample
678 case 67866:
679 {
681 unitTarget->CastSpell(unitTarget, 67867, false);
682 return;
683 }
684 // Trial of the Champion, Hammer of the Righteous
685 case 66867:
686 {
687 if (!unitTarget)
688 return;
689 if (unitTarget->HasAura(66940))
690 m_caster->CastSpell(unitTarget, 66903, true);
691 else
692 m_caster->CastSpell(unitTarget, 66904, true);
693 return;
694 }
695 case 17731:
696 case 69294:
697 {
699 return;
700
704 trigger->CastSpell(trigger, 17731, false);
705
706 return;
707 }
708 // HoL, Arc Weld
709 case 59086:
710 {
712 m_caster->CastSpell(m_caster, 59097, true);
713
714 return;
715 }
716 }
717 break;
718 }
720 switch (m_spellInfo->Id)
721 {
722 case 31789: // Righteous Defense (step 1)
723 {
724 if (!unitTarget)
725 return;
726 // not empty (checked), copy
728
729 // remove invalid attackers
730 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
731 if (!(*aItr)->IsValidAttackTarget(m_caster))
732 aItr = attackers.erase(aItr);
733 else
734 ++aItr;
735
736 // selected from list 3
737 uint32 maxTargets = std::min<uint32>(3, attackers.size());
738 for (uint32 i = 0; i < maxTargets; ++i)
739 {
740 Unit::AttackerSet::iterator aItr = attackers.begin();
741 std::advance(aItr, urand(0, attackers.size() - 1));
742 m_caster->CastSpell((*aItr), 31790, true);
743 attackers.erase(aItr);
744 }
745
746 return;
747 }
748 }
749 break;
751 // Hunger for Blood
752 if (m_spellInfo->Id == 51662)
753 {
754 m_caster->CastSpell(m_caster, 63848, true);
755 return;
756 }
757 break;
758 }
759
760 // pet auras
761 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
762 {
763 m_caster->AddPetAura(petSpell);
764 return;
765 }
766
767 // normal DB scripted effect
768 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
770
771 if (gameObjTarget)
772 {
773 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
774 }
775 else if (unitTarget && unitTarget->IsCreature())
776 {
777 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
778 }
779 else if (itemTarget)
780 {
781 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
782 }
783}
@ SPELLFAMILY_GENERIC
Definition: SharedDefines.h:3528
@ SPELLFAMILY_PALADIN
Definition: SharedDefines.h:3538
@ SPELLFAMILY_ROGUE
Definition: SharedDefines.h:3536
ScriptMapMap sSpellScripts
Definition: ObjectMgr.cpp:59
@ TEMPSUMMON_TIMED_DESPAWN
Definition: Object.h:47
@ UNIT_FIELD_MOUNTDISPLAYID
Definition: UpdateFields.h:126
uint8 GetGoAnimProgress() const
Definition: GameObject.h:209
time_t GetRespawnTime() const
Definition: GameObject.h:183
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition: Object.cpp:2355
void AddPetAura(PetAura const *petSpell)
Definition: Unit.cpp:17293
std::unordered_set< Unit * > AttackerSet
Definition: Unit.h:632
AttackerSet const & getAttackers() const
Definition: Unit.h:850
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition: MapScripts.cpp:31
Definition: SpellMgr.h:470

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetUInt32Value(), Unit::HasAura(), SpellInfo::Id, Object::IsCreature(), Unit::isMoving(), Object::IsPlayer(), Unit::IsVehicle(), itemTarget, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), GameObject::SendCustomAnim(), GameObject::SetRespawnTime(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sScriptMgr, sSpellMgr, sSpellScripts, WorldObject::SummonCreature(), TEMPSUMMON_TIMED_DESPAWN, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_MOUNTDISPLAYID, unitTarget, and urand().

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5283{
5285 return;
5286
5287 if (!unitTarget)
5288 return;
5289
5290 Player* player = unitTarget->ToPlayer();
5291 if (!player)
5292 {
5293 return;
5294 }
5295
5296 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5297
5298 // -1 means all player equipped items and -2 all items
5299 if (slot < 0)
5300 {
5301 player->DurabilityPointsLossAll(damage, (slot < -1));
5303 return;
5304 }
5305
5306 // invalid slot value
5307 if (slot >= INVENTORY_SLOT_BAG_END)
5308 return;
5309
5310 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5311 {
5312 player->DurabilityPointsLoss(item, damage);
5313 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5314 }
5315}
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:700
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:670
Item * GetItemByPos(uint16 pos) const
Definition: PlayerStorage.cpp:441
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition: Player.cpp:4754
void DurabilityPointsLoss(Item *item, int32 points)
Definition: Player.cpp:4780
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition: Spell.cpp:5131

References damage, Player::DurabilityPointsLoss(), Player::DurabilityPointsLossAll(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDurabilityDamage(), Object::GetEntry(), Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectDurabilityDamagePCT()

void Spell::EffectDurabilityDamagePCT ( SpellEffIndex  effIndex)
5318{
5320 return;
5321
5322 if (!unitTarget)
5323 return;
5324
5325 Player* player = unitTarget->ToPlayer();
5326 if (!player)
5327 {
5328 return;
5329 }
5330
5331 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5332
5333 // FIXME: some spells effects have value -1/-2
5334 // Possibly its mean -1 all player equipped items and -2 all items
5335 if (slot < 0)
5336 {
5337 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5338 return;
5339 }
5340
5341 // invalid slot value
5342 if (slot >= INVENTORY_SLOT_BAG_END)
5343 return;
5344
5345 if (damage <= 0)
5346 return;
5347
5348 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5349 player->DurabilityLoss(item, float(damage) / 100.0f);
5350}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4710
void DurabilityLoss(Item *item, double percent)
Definition: Player.cpp:4736

References damage, Player::DurabilityLoss(), Player::DurabilityLossAll(), effectHandleMode, SpellInfo::Effects, Player::GetItemByPos(), INVENTORY_SLOT_BAG_0, INVENTORY_SLOT_BAG_END, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantHeldItem()

void Spell::EffectEnchantHeldItem ( SpellEffIndex  effIndex)
4418{
4420 return;
4421
4422 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4423 if (!unitTarget)
4424 return;
4425
4426 Player* item_owner = unitTarget->ToPlayer();
4427 if (!item_owner)
4428 {
4429 return;
4430 }
4431
4433 if (!item)
4434 return;
4435
4436 // must be equipped
4437 if (!item->IsEquipped())
4438 return;
4439
4440 if (m_spellInfo->Effects[effIndex].MiscValue)
4441 {
4442 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4443 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4444 if (!duration)
4445 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4446 if (!duration)
4447 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4448
4449 // Xinef: Venomhide poison, no other spell uses this effect...
4450 if (m_spellInfo->Id == 14792)
4451 duration = 5 * MINUTE * IN_MILLISECONDS;
4452
4453 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4454 if (!pEnchant)
4455 return;
4456
4457 // Always go to temp enchantment slot
4459
4460 // Enchantment will not be applied if a different one already exists
4461 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4462 return;
4463
4464 // Apply the temporary enchantment
4465 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, m_caster->GetGUID());
4466 item_owner->ApplyEnchantment(item, slot, true);
4467 }
4468}
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:690
EnchantmentSlot
Definition: Item.h:168
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:170
bool IsEquipped() const
Definition: Item.cpp:789
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:920
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Definition: PlayerStorage.cpp:4304
uint32 charges
Definition: DBCStructure.h:1842

References Player::ApplyEnchantment(), SpellItemEnchantmentEntry::charges, damage, effectHandleMode, SpellInfo::Effects, EQUIPMENT_SLOT_MAINHAND, SpellInfo::GetDuration(), Item::GetEnchantmentId(), Object::GetGUID(), Player::GetItemByPos(), SpellInfo::Id, IN_MILLISECONDS, INVENTORY_SLOT_BAG_0, Item::IsEquipped(), m_caster, m_spellInfo, MINUTE, Item::SetEnchantment(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
2830{
2832 return;
2833
2834 if (!m_caster->IsPlayer())
2835 return;
2836 if (!itemTarget)
2837 return;
2838
2839 Player* p_caster = m_caster->ToPlayer();
2840
2841 // Handle vellums
2843 {
2844 // destroy one vellum from stack
2845 uint32 count = 1;
2846 p_caster->DestroyItemCount(itemTarget, count, true);
2847 unitTarget = p_caster;
2848 // and add a scroll
2849 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
2850 itemTarget = nullptr;
2851 m_targets.SetItemTarget(nullptr);
2852 }
2853 else
2854 {
2855 // do not increase skill if vellum used
2857 p_caster->UpdateCraftSkill(m_spellInfo->Id);
2858
2859 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2860 if (!enchant_id)
2861 return;
2862
2863 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2864 if (!pEnchant)
2865 return;
2866
2867 // item can be in trade slot and have owner diff. from caster
2868 Player* item_owner = itemTarget->GetOwner();
2869 if (!item_owner)
2870 return;
2871
2872 // remove old enchanting before applying new if equipped
2874
2876
2877 // add new enchanting if equipped
2879
2880 item_owner->RemoveTradeableItem(itemTarget);
2882 }
2883}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:169
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1264
void RemoveTradeableItem(Item *item)
Definition: PlayerStorage.cpp:4139
void SetItemTarget(Item *item)
Definition: Spell.cpp:328

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), Player::DestroyItemCount(), DoCreateItem(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Item::GetTemplate(), ItemTemplate::HasFlag(), SpellInfo::Id, Item::IsArmorVellum(), Object::IsPlayer(), Item::IsWeaponVellum(), ITEM_FLAG_NO_REAGENT_COST, itemTarget, m_caster, m_CastItem, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, Object::ToPlayer(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
2886{
2888 return;
2889
2890 if (!m_caster->IsPlayer())
2891 return;
2892 if (!itemTarget)
2893 return;
2894
2895 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
2896 if (!enchant_id)
2897 return;
2898
2899 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
2900 if (!pEnchant)
2901 return;
2902
2903 // support only enchantings with add socket in this slot
2904 {
2905 bool add_socket = false;
2906 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
2907 {
2908 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
2909 {
2910 add_socket = true;
2911 break;
2912 }
2913 }
2914 if (!add_socket)
2915 {
2916 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemPrismatic: attempt apply enchant spell {} with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC ({}) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET ({}), not suppoted yet.",
2918 return;
2919 }
2920 }
2921
2922 // item can be in trade slot and have owner diff. from caster
2923 Player* item_owner = itemTarget->GetOwner();
2924 if (!item_owner)
2925 return;
2926
2927 // remove old enchanting before applying new if equipped
2929
2931
2932 // add new enchanting if equipped
2934
2935 item_owner->RemoveTradeableItem(itemTarget);
2937}

References Player::ApplyEnchantment(), Item::ClearSoulboundTradeable(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), SpellInfo::Id, Object::IsPlayer(), ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET, itemTarget, LOG_ERROR, m_caster, m_spellInfo, MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS, PRISMATIC_ENCHANTMENT_SLOT, Player::RemoveTradeableItem(), Item::SetEnchantment(), SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC, SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellItemEnchantmentStore, and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2940{
2942 return;
2943
2944 if (!m_caster->IsPlayer())
2945 return;
2946
2947 Player* p_caster = m_caster->ToPlayer();
2948
2949 // Rockbiter Weapon apply to both weapon
2950 if (!itemTarget)
2951 return;
2953 {
2954 uint32 spell_id = 0;
2955
2956 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
2957 // Note: damage calculated (correctly) with rounding int32(float(v)) but
2958 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
2959 switch (damage)
2960 {
2961 // Rank 1
2962 case 2:
2963 spell_id = 36744;
2964 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
2965 // Rank 2
2966 case 4:
2967 spell_id = 36753;
2968 break; // 0% [ 7% == 4, 14% == 4]
2969 case 5:
2970 spell_id = 36751;
2971 break; // 20%
2972 // Rank 3
2973 case 6:
2974 spell_id = 36754;
2975 break; // 0% [ 7% == 6, 14% == 6]
2976 case 7:
2977 spell_id = 36755;
2978 break; // 20%
2979 // Rank 4
2980 case 9:
2981 spell_id = 36761;
2982 break; // 0% [ 7% == 6]
2983 case 10:
2984 spell_id = 36758;
2985 break; // 14%
2986 case 11:
2987 spell_id = 36760;
2988 break; // 20%
2989 default:
2990 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
2991 return;
2992 }
2993
2994 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
2995 if (!spellInfo)
2996 {
2997 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
2998 return;
2999 }
3000
3001 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
3002 {
3003 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
3004 {
3005 if (item->IsFitToSpellRequirements(m_spellInfo))
3006 {
3007 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
3008 SpellCastTargets targets;
3009 targets.SetItemTarget(item);
3010 spell->prepare(&targets);
3011 }
3012 }
3013 }
3014 return;
3015 }
3016 if (!itemTarget)
3017 return;
3018
3019 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3020
3021 if (!enchant_id)
3022 {
3023 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3024 return;
3025 }
3026
3027 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3028 if (!pEnchant)
3029 {
3030 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3031 return;
3032 }
3033
3034 // select enchantment duration
3035 uint32 duration;
3036
3037 // rogue family enchantments exception by duration
3038 if (m_spellInfo->Id == 38615)
3039 duration = 1800; // 30 mins
3040 // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints)
3042 duration = 3600; // 1 hour
3043 // shaman family enchantments
3045 duration = 1800; // 30 mins
3046 // other cases with this SpellVisual already selected
3047 else if (m_spellInfo->SpellVisual[0] == 215)
3048 duration = 1800; // 30 mins
3049 // some fishing pole bonuses except Glow Worm which lasts full hour
3050 else if (m_spellInfo->SpellVisual[0] == 563 && m_spellInfo->Id != 64401)
3051 duration = 600; // 10 mins
3052 // shaman rockbiter enchantments
3053 else if (m_spellInfo->SpellVisual[0] == 0)
3054 duration = 1800; // 30 mins
3055 else if (m_spellInfo->Id == 29702)
3056 duration = 300; // 5 mins
3057 else if (m_spellInfo->Id == 37360)
3058 duration = 300; // 5 mins
3059 // default case
3060 else
3061 duration = 3600; // 1 hour
3062
3063 // item can be in trade slot and have owner diff. from caster
3064 Player* item_owner = itemTarget->GetOwner();
3065 if (!item_owner)
3066 return;
3067
3068 // remove old enchanting before applying new if equipped
3070
3071 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3072
3073 // add new enchanting if equipped
3075
3076 item_owner->RemoveTradeableItem(itemTarget);
3078}
@ SPELLFAMILY_SHAMAN
Definition: SharedDefines.h:3539
WeaponAttackType
Definition: Unit.h:208
Definition: Spell.h:111
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3476
std::array< uint32, 2 > SpellVisual
Definition: SpellInfo.h:379

References Player::ApplyEnchantment(), BASE_ATTACK, SpellItemEnchantmentEntry::charges, Item::ClearSoulboundTradeable(), damage, effectHandleMode, SpellInfo::Effects, Object::GetGUID(), Item::GetOwner(), Player::GetWeaponForAttack(), SpellInfo::Id, Object::IsPlayer(), itemTarget, LOG_ERROR, m_caster, m_spellInfo, OFF_ATTACK, prepare(), Player::RemoveTradeableItem(), Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellVisual, sSpellItemEnchantmentStore, sSpellMgr, TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1879{
1881 return;
1882
1883 if (!unitTarget)
1884 return;
1885 if (!unitTarget->IsAlive())
1886 return;
1887
1889 {
1891 return;
1892 }
1893
1894 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1895 return;
1896
1897 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1898
1901 return;
1902
1903 if (unitTarget->GetMaxPower(power) == 0)
1904 return;
1905
1906 // Some level depends spells
1907 int level_multiplier = 0;
1908 int level_diff = 0;
1909 switch (m_spellInfo->Id)
1910 {
1911 case 9512: // Restore Energy
1912 level_diff = m_caster->GetLevel() - 40;
1913 level_multiplier = 2;
1914 break;
1915 case 24571: // Blood Fury
1916 level_diff = m_caster->GetLevel() - 60;
1917 level_multiplier = 10;
1918 break;
1919 case 24532: // Burst of Energy
1920 level_diff = m_caster->GetLevel() - 60;
1921 level_multiplier = 4;
1922 break;
1923 case 31930: // Judgements of the Wise
1924 case 63375: // Improved Stormstrike
1925 case 68082: // Glyph of Seal of Command
1927 break;
1928 case 48542: // Revitalize
1930 break;
1931 case 71132: // Glyph of Shadow Word: Pain
1932 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
1933 break;
1934 default:
1935 break;
1936 }
1937
1938 if (level_diff > 0)
1939 damage -= level_multiplier * level_diff;
1940
1941 if (damage < 0)
1942 return;
1943
1945
1946 // Mad Alchemist's Potion
1947 if (m_spellInfo->Id == 45051)
1948 {
1949 // find elixirs on target
1950 bool guardianFound = false;
1951 bool battleFound = false;
1953 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
1954 {
1955 SpellGroupSpecialFlags sFlag = sSpellMgr->GetSpellGroupSpecialFlags(itr->second->GetBase()->GetId());
1956 if (!guardianFound)
1958 guardianFound = true;
1959 if (!battleFound)
1961 battleFound = true;
1962 if (battleFound && guardianFound)
1963 break;
1964 }
1965
1966 // get all available elixirs by mask and spell level
1967 std::set<uint32> availableElixirs;
1968 if (!guardianFound)
1969 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, availableElixirs);
1970 if (!battleFound)
1971 sSpellMgr->GetSetOfSpellsInSpellGroupWithFlag(1, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, availableElixirs);
1972 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
1973 {
1974 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
1975 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
1976 availableElixirs.erase(itr++);
1977 else
1978 ++itr;
1979 }
1980
1981 if (!availableElixirs.empty())
1982 {
1983 // cast random elixir on target
1985 }
1986 }
1987}
@ SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED
Definition: SharedDefines.h:657
@ SPELLFAMILY_POTION
Definition: SharedDefines.h:3541
SpellGroupSpecialFlags
Definition: SpellMgr.h:334
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE
Definition: SpellMgr.h:336
@ SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN
Definition: SpellMgr.h:337
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:133
void EnergizeBySpell(Unit *victim, uint32 SpellID, uint32 Damage, Powers powertype)
Definition: Unit.cpp:11266
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition: Unit.cpp:6469

References CalculatePct(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetAppliedAuras(), Unit::GetCreateMana(), Unit::GetLevel(), Unit::GetMaxPower(), GetSpellInfo(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_CastItem, m_spellInfo, MAX_POWERS, Acore::Containers::SelectRandomContainerElement(), Unit::SendSpellDamageImmune(), SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_BATTLE, SPELL_GROUP_SPECIAL_FLAG_ELIXIR_GUARDIAN, SPELLFAMILY_POTION, SpellInfo::SpellFamilyName, SpellInfo::SpellLevel, sSpellMgr, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectEnergizePct()

void Spell::EffectEnergizePct ( SpellEffIndex  effIndex)
1990{
1992 return;
1993
1994 if (!unitTarget)
1995 return;
1996 if (!unitTarget->IsAlive())
1997 return;
1998
1999 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2000 return;
2001
2002 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2003
2005 return;
2006
2007 uint32 maxPower = unitTarget->GetMaxPower(power);
2008 if (maxPower == 0)
2009 return;
2010
2011 uint32 gain = CalculatePct(maxPower, damage);
2013}

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, MAX_POWERS, SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectEnvironmentalDMG()

void Spell::EffectEnvironmentalDMG ( SpellEffIndex  effIndex)
299{
301 return;
302
303 if (!unitTarget || !unitTarget->IsAlive())
304 return;
305
306 if (unitTarget->IsPlayer())
308 else
309 {
311
312 uint32 absorb = dmgInfo.GetAbsorb();
313 uint32 resist = dmgInfo.GetResist();
314 uint32 envDamage = dmgInfo.GetDamage();
315
316 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
317 damage = envDamage;
318
320 }
321}
@ DAMAGE_FIRE
Definition: Player.h:839
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition: Player.cpp:755

References damage, DAMAGE_FIRE, Unit::DealDamageMods(), effectHandleMode, Player::EnvironmentalDamage(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), DamageInfo::GetResist(), SpellInfo::GetSchoolMask(), Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, Unit::SendSpellNonMeleeDamageLog(), SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectFeedPet()

void Spell::EffectFeedPet ( SpellEffIndex  effIndex)
Todo:
: fix crash when a spell has two effects, both pointed at the same item target
4524{
4526 return;
4527
4528 Player* player = m_caster->ToPlayer();
4529 if (!player)
4530 return;
4531
4532 Item* foodItem = itemTarget;
4533 if (!foodItem)
4534 return;
4535
4536 Pet* pet = player->GetPet();
4537 if (!pet)
4538 return;
4539
4540 if (!pet->IsAlive())
4541 return;
4542
4543 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4544 if (benefit <= 0)
4545 return;
4546
4547 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4548
4549 uint32 count = 1;
4550 player->DestroyItemCount(foodItem, count, true);
4552
4553 m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4554}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition: Spell.cpp:5151

References Unit::CastCustomSpell(), Player::DestroyItemCount(), effectHandleMode, SpellInfo::Effects, ExecuteLogEffectDestroyItem(), Pet::GetCurrentFoodBenefitLevel(), Object::GetEntry(), Player::GetPet(), Item::GetTemplate(), Unit::IsAlive(), ItemTemplate::ItemLevel, itemTarget, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToPlayer().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
997{
999 return;
1000
1001 if (!unitTarget)
1002 return;
1003
1004 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1005
1006 // normal case
1007 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1008
1009 if (!spellInfo)
1010 {
1011 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1012 return;
1013 }
1014
1015 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1016 {
1017 switch (m_spellInfo->Id)
1018 {
1019 case 52588: // Skeletal Gryphon Escape
1020 case 48598: // Ride Flamebringer Cue
1022 break;
1023 case 52463: // Hide In Mine Car
1024 case 52349: // Overtake
1025 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1026 return;
1027 case 72378: // Blood Nova
1028 case 73058: // Blood Nova
1029 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1030 break;
1031 }
1032 }
1033
1034 CustomSpellValues values;
1035 // set basepoints for trigger with value effect
1037 {
1038 // maybe need to set value only when basepoints == 0?
1042 }
1043
1044 SpellCastTargets targets;
1045 targets.SetUnitTarget(m_caster);
1046
1047 unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
1048}
@ SPELL_EFFECT_FORCE_CAST
Definition: SharedDefines.h:918
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition: SharedDefines.h:919
@ SPELLVALUE_BASE_POINT1
Definition: SpellDefines.h:114
@ SPELLVALUE_BASE_POINT2
Definition: SpellDefines.h:115
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:113
Definition: SpellDefines.h:162
void AddSpellMod(SpellValueMod mod, int32 value)
Definition: SpellDefines.h:164

References CustomSpellValues::AddSpellMod(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_caster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_FORCE_CAST, SPELL_EFFECT_FORCE_CAST_WITH_VALUE, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4780{
4782 return;
4783
4784 // xinef: clear focus
4786
4788 data << m_caster->GetGUID();
4789
4791 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4792 Cell::VisitWorldObjects(m_caster, notifier, dist);
4793
4794 // xinef: we should also force pets to remove us from current target
4795 Unit::AttackerSet attackerSet;
4796 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4797 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4798 attackerSet.insert(*itr);
4799
4800 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4801 (*itr)->AttackStop();
4802
4803 // Xinef: Mirror images code Initialize Images
4804 if (m_spellInfo->Id == 58836)
4805 {
4806 std::vector<Unit*> images;
4807 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4808 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4809 images.push_back(*itr);
4810
4811 if (images.empty())
4812 return;
4813
4814 UnitList targets;
4815 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4818 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4819 {
4820 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4821 continue;
4822
4823 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4824 {
4825 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4826 {
4827 SpellInfo const* si = spell->GetSpellInfo();
4828 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4829 {
4830 Creature* c = (*iter)->ToCreature();
4831 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4832 continue;
4833 }
4834
4835 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4836 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4837 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4838 {
4839 // at least one effect truly targets an unit, interrupt the spell
4840 interrupt = true;
4841 break;
4842 }
4843
4844 if (interrupt)
4845 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4846 }
4847 }
4848 }
4849 }
4850}
@ CREATURE_ELITE_WORLDBOSS
Definition: SharedDefines.h:2734
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition: SharedDefines.h:617
@ TARGET_OBJECT_TYPE_UNIT
Definition: SpellInfo.h:101
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition: SpellInfo.h:102
#define VISIBILITY_COMPENSATION
Definition: ObjectDefines.h:26
std::list< Unit * > UnitList
Definition: Unit.h:76
@ SMSG_CLEAR_TARGET
Definition: Opcodes.h:989
bool IsDungeonBoss() const
Definition: Creature.cpp:3160
uint32 rank
Definition: CreatureData.h:206
ControlSet m_Controlled
Definition: Unit.h:1894
void SendClearTarget()
Definition: Unit.cpp:20322
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:206
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:192
Definition: GridNotifiers.h:133
Definition: GridNotifiers.h:423
Definition: GridNotifiers.h:861

References CREATURE_ELITE_WORLDBOSS, CURRENT_GENERIC_SPELL, effectHandleMode, SpellInfo::Effects, Unit::getAttackers(), Creature::GetCreatureTemplate(), Object::GetGUID(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), m_caster, Unit::m_Controlled, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::SendClearTarget(), SMSG_CLEAR_TARGET, SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), UNIT_STATE_CASTING, urand(), VISIBILITY_COMPENSATION, Cell::VisitAllObjects(), and Cell::VisitWorldObjects().

◆ EffectGameObjectDamage()

void Spell::EffectGameObjectDamage ( SpellEffIndex  effIndex)
5915{
5917 return;
5918
5919 if (!gameObjTarget)
5920 return;
5921
5922 Unit* caster = m_originalCaster;
5923 if (!caster)
5924 return;
5925
5926 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5928 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5929 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5931}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition: GameObject.cpp:2277
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:10034
Definition: DBCStructure.h:938
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:950

References damage, effectHandleMode, GAMEOBJECT_FACTION, gameObjTarget, Unit::GetFactionTemplateEntry(), GetSpellInfo(), Object::GetUInt32Value(), FactionTemplateEntry::IsFriendlyTo(), m_originalCaster, GameObject::ModifyHealth(), sFactionTemplateStore, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectGameObjectRepair()

void Spell::EffectGameObjectRepair ( SpellEffIndex  effIndex)

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
5945{
5947 return;
5948
5950 return;
5951
5954}
GameObjectDestructibleState
Definition: SharedDefines.h:1626
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition: GameObject.cpp:2340

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

void Spell::EffectHeal ( SpellEffIndex  effIndex)
1473{
1475 return;
1476
1477 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1478 {
1479 // Try to get original caster
1481
1482 // Skip if m_originalCaster not available
1483 if (!caster)
1484 return;
1485
1486 int32 addhealth = damage;
1487
1488 // Vessel of the Naaru (Vial of the Sunwell trinket)
1489 if (m_spellInfo->Id == 45064)
1490 {
1491 // Amount of heal - depends from stacked Holy Energy
1492 int damageAmount = 0;
1493 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(45062, 0))
1494 {
1495 damageAmount += aurEff->GetAmount();
1497 }
1498
1499 addhealth += damageAmount;
1500 }
1501 // Swiftmend - consumes Regrowth or Rejuvenation
1503 {
1505 // find most short by duration
1506 AuraEffect* forcedTargetAura = nullptr;
1507 AuraEffect* targetAura = nullptr;
1508 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1509 {
1510 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1511 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1512 {
1513 if (m_caster->GetGUID() == (*i)->GetCasterGUID())
1514 {
1515 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1516 forcedTargetAura = *i;
1517 }
1518 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1519 targetAura = *i;
1520 }
1521 }
1522
1523 if (forcedTargetAura)
1524 targetAura = forcedTargetAura;
1525
1526 if (!targetAura)
1527 {
1528 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1529 return;
1530 }
1531
1532 int32 tickheal = targetAura->GetAmount();
1533 if (Unit* auraCaster = targetAura->GetCaster())
1534 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1535
1536 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1537 //It is said that talent bonus should not be included
1538
1539 int32 tickcount = 0;
1540 // Rejuvenation
1541 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1542 tickcount = 4;
1543 // Regrowth
1544 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1545 tickcount = 6;
1546
1547 addhealth += tickheal * tickcount;
1548
1549 // Glyph of Swiftmend
1550 if (!caster->HasAura(54824))
1551 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1552
1553 //addhealth += tickheal * tickcount;
1554 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1555 }
1556 // Death Pact - return pct of max health to caster
1558 {
1559 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1560 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1561 }
1562 else if (m_spellInfo->Id != 33778) // not lifebloom
1563 {
1564 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1565 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1566 }
1567
1568 // Implemented this way as there is no other way to do it currently (that I know :P)...
1569 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1570 {
1572 {
1573 m_damage = 0;
1574 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1575 return;
1576 }
1577 }
1578
1579 m_damage -= addhealth;
1580 }
1581}
@ SPELLFAMILY_DRUID
Definition: SharedDefines.h:3535
@ SPELLFAMILY_DEATHKNIGHT
Definition: SharedDefines.h:3543
@ AURA_STATE_SWIFTMEND
Definition: SharedDefines.h:1307
@ SPELL_SCHOOL_MASK_HOLY
Definition: SharedDefines.h:298
@ SPELL_AURA_PERIODIC_HEAL
Definition: SpellAuraDefines.h:71
@ DOT
Definition: Unit.h:250
uint32 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:1042
SpellInfo const * GetSpellInfo() const
Definition: SpellAuraEffects.h:54
uint32 GetId() const
Definition: SpellAuraEffects.cpp:432
Unit * GetCaster() const
Definition: SpellAuraEffects.h:47
Aura * GetBase() const
Definition: SpellAuraEffects.h:49
ObjectGuid GetCasterGUID() const
Definition: SpellAuraEffects.h:48
int32 GetAmount() const
Definition: SpellAuraEffects.h:64
uint32 TargetAuraState
Definition: SpellInfo.h:340

References AURA_STATE_SWIFTMEND, Unit::CastSpell(), Unit::CountPctFromMaxHealth(), damage, DOT, effectHandleMode, AuraEffect::GetAmount(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), AuraEffect::GetCaster(), AuraEffect::GetCasterGUID(), Aura::GetDuration(), Object::GetGUID(), AuraEffect::GetId(), SpellInfo::GetSchoolMask(), AuraEffect::GetSpellInfo(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, m_caster, m_damage, m_originalCaster, m_originalCasterGUID, m_spellInfo, Unit::RemoveAura(), Unit::RemoveAurasDueToSpell(), SPELL_AURA_PERIODIC_HEAL, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_SCHOOL_MASK_HOLY, SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Unit::SpellHealingBonusDone(), Unit::SpellHealingBonusTaken(), SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3681{
3683 return;
3684
3685 if (!unitTarget || !unitTarget->IsAlive())
3686 return;
3687
3689 {
3691 return;
3692 }
3693
3694 int32 addhealth = 0;
3695
3696 // damage == 0 - heal for caster max health
3697 if (damage == 0)
3698 addhealth = m_caster->GetMaxHealth();
3699 else
3700 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3701
3702 m_healing += addhealth;
3703}
uint32 GetMaxHealth() const
Definition: Unit.h:1030

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), GetSpellInfo(), Unit::HasUnitState(), Unit::IsAlive(), m_caster, m_healing, Unit::SendSpellDamageImmune(), SPELL_EFFECT_HANDLE_HIT_TARGET, UNIT_STATE_ISOLATED, and unitTarget.

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

void Spell::EffectHealPct ( SpellEffIndex  effIndex)

◆ EffectHealthLeech()

void Spell::EffectHealthLeech ( SpellEffIndex  effIndex)
1619{
1621 return;
1622
1623 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1624 return;
1625
1628
1629 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1630
1631 // xinef: handled in spell.cpp
1632 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1633
1634 m_damage += damage;
1635 // get max possible damage, don't count overkill for heal
1636 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1637
1638 //if (m_caster->IsAlive())
1639 //{
1640 // healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
1641 // healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
1642
1643 // m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
1644 //}
1645}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition: Unit.cpp:11786
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition: Unit.cpp:11610

References damage, effectHandleMode, Unit::IsAlive(), LOG_DEBUG, m_caster, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4488{
4490 return;
4491
4492 if (!unitTarget)
4493 return;
4494
4495 Player* player = unitTarget->ToPlayer();
4496 if (!player)
4497 {
4498 return;
4499 }
4500
4501 uint8 currentDrunk = player->GetDrunkValue();
4502 int32 drunkMod = damage;
4503
4504 if (drunkMod == 0)
4505 return;
4506
4507 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4508 // In addition, we would not want currentDrunk to become more than 100.
4509 // So before adding the values, let's check that everything is fine.
4510 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4511 currentDrunk = 100;
4512 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4513 currentDrunk = 0;
4514 else
4515 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4516
4517 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4518
4519 if (currentDrunk == 100 && roll_chance_i(25))
4520 player->CastSpell(player, 67468, false); // Drunken Vomit
4521}
uint8 GetDrunkValue() const
Definition: Player.h:2154
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition: Player.cpp:972

References Unit::CastSpell(), damage, effectHandleMode, Player::GetDrunkValue(), Object::GetEntry(), m_CastItem, roll_chance_i(), Player::SetDrunkValue(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
275{
277 return;
278
279 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
280 return;
281
282 if (unitTarget->IsPlayer())
284 return;
285
286 if (m_caster == unitTarget) // prevent interrupt message
287 finish();
288
289 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
290 data << m_caster->GetGUID();
291 data << unitTarget->GetGUID();
292 data << uint32(m_spellInfo->Id);
293 m_caster->SendMessageToSet(&data, true);
294
296}
@ SPELL_SCHOOL_MASK_NORMAL
Definition: SharedDefines.h:297
@ CHEAT_GOD
Definition: Player.h:999
@ SMSG_SPELLINSTAKILLLOG
Definition: Opcodes.h:845
static uint32 DealDamage(Unit *attacker, Unit *victim, uint32 damage, CleanDamage const *cleanDamage=nullptr, DamageEffectType damagetype=DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *spellProto=nullptr, bool durabilityLoss=true, bool allowGM=false, Spell const *spell=nullptr)
Definition: Unit.cpp:810

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), m_caster, m_spellInfo, NODAMAGE, WorldObject::SendMessageToSet(), SMSG_SPELLINSTAKILLLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_SCHOOL_MASK_NORMAL, Object::ToPlayer(), and unitTarget.

◆ EffectInterruptCast()

void Spell::EffectInterruptCast ( SpellEffIndex  effIndex)
Todo:
: not all spells that used this effect apply cooldown at school spells
3706{
3708 return;
3709
3710 if (!unitTarget || !unitTarget->IsAlive())
3711 return;
3712
3714 // also exist case: apply cooldown to interrupted cast only and to all spells
3715 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3717 {
3719 {
3720 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3721 // check if we can interrupt spell
3722 if ((spell->getState() == SPELL_STATE_CASTING
3723 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3727 {
3728 if (m_originalCaster)
3729 {
3731 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3732 }
3733 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3735 }
3736 }
3737 }
3738}
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:37
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition: SpellDefines.h:29
#define CURRENT_FIRST_NON_MELEE_SPELL
Definition: Unit.h:543
CurrentSpellTypes
Definition: Unit.h:536
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:539
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:540
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4060
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition: Unit.cpp:14851
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition: Unit.h:1456
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition: Spell.cpp:5124
uint32 ChannelInterruptFlags
Definition: SpellInfo.h:354
uint32 InterruptFlags
Definition: SpellInfo.h:352

References Unit::CalcSpellDuration(), CHANNEL_INTERRUPT_FLAG_INTERRUPT, SpellInfo::ChannelInterruptFlags, CURRENT_AUTOREPEAT_SPELL, CURRENT_CHANNELED_SPELL, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_GENERIC_SPELL, effectHandleMode, ExecuteLogEffectInterruptCast(), Unit::GetCurrentSpell(), SpellInfo::GetSchoolMask(), SpellInfo::Id, SpellInfo::InterruptFlags, Unit::InterruptSpell(), Unit::IsAlive(), m_originalCaster, m_spellInfo, Unit::ModSpellDuration(), SpellInfo::PreventionType, Unit::ProhibitSpellSchool(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_INTERRUPT_FLAG_INTERRUPT, SPELL_PREVENTION_TYPE_SILENCE, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, and unitTarget.

◆ EffectJump()

void Spell::EffectJump ( SpellEffIndex  effIndex)
1070{
1072 return;
1073
1074 if (m_caster->IsInFlight())
1075 return;
1076
1077 if (!unitTarget)
1078 return;
1079
1080 float speedXY, speedZ;
1081 CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
1082 m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1083
1084 if (m_caster->IsPlayer())
1085 {
1086 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1087 }
1088}
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:165
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition: MotionMaster.h:229
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition: SpellEffects.cpp:1153

References CalculateJumpSpeeds(), effectHandleMode, Position::GetExactDist2d(), Unit::GetMotionMaster(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1091{
1093 return;
1094
1095 if (m_caster->IsInFlight())
1096 return;
1097
1098 if (!m_targets.HasDst() || m_caster->GetVehicle())
1099 return;
1100
1101 // Init dest coordinates
1102 float x, y, z;
1103 destTarget->GetPosition(x, y, z);
1104 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1105 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1106 return;
1107
1108 float speedXY, speedZ;
1109 float dist = m_caster->GetExactDist2d(x, y);
1110 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1111
1112 // Override, calculations are incorrect
1113 if (m_spellInfo->Id == 49376) // feral charge
1114 {
1115 speedXY = pow(speedZ * 10, 8);
1117
1118 if (Player* player = m_caster->ToPlayer())
1119 {
1120 player->SetCanTeleport(true);
1121 }
1122
1123 if (m_caster->IsPlayer())
1124 {
1125 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1126 }
1127
1128 return;
1129 }
1130
1131 if (m_spellInfo->Id == 57604) // death grip
1132 {
1133 speedZ = 3.0f;
1134 speedXY = 50.0f;
1135 }
1136
1137 // crash fix?
1138 if (speedXY < 1.0f)
1139 speedXY = 1.0f;
1140
1141 if (Player* player = m_caster->ToPlayer())
1142 {
1143 player->SetCanTeleport(true);
1144 }
1145 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1146
1147 if (m_caster->IsPlayer())
1148 {
1149 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1150 }
1151}
#define INVALID_HEIGHT
Definition: Map.h:163
@ UNIT_FIELD_TARGET
Definition: UpdateFields.h:92
bool IsValidMapCoord(float c)
Definition: GridDefines.h:215
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337

References CalculateJumpSpeeds(), destTarget, effectHandleMode, Position::GetExactDist2d(), Object::GetGuidValue(), Unit::GetMotionMaster(), Position::GetPosition(), ObjectAccessor::GetUnit(), Unit::GetVehicle(), SpellCastTargets::HasDst(), SpellInfo::Id, INVALID_HEIGHT, Unit::IsInFlight(), Object::IsPlayer(), Acore::IsValidMapCoord(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, Object::ToPlayer(), and UNIT_FIELD_TARGET.

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
5707{
5709 return;
5710
5711 if (!unitTarget)
5712 return;
5713
5715 if (!player)
5716 {
5717 return;
5718 }
5719
5720 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5721 if (!creatureEntry)
5722 {
5723 if (m_spellInfo->Id == 42793) // Burn Body
5724 creatureEntry = 24008; // Fallen Combatant
5725 }
5726
5727 if (creatureEntry)
5728 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5729}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition: Player.cpp:12744

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), SpellInfo::Id, m_spellInfo, Player::RewardPlayerAndGroupAtEvent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKillCreditPersonal()

void Spell::EffectKillCreditPersonal ( SpellEffIndex  effIndex)
5693{
5695 return;
5696
5697 if (!unitTarget)
5698 return;
5699
5701 {
5702 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5703 }
5704}

References effectHandleMode, SpellInfo::Effects, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
4984{
4986 return;
4987
4988 if (!unitTarget)
4989 return;
4990
4991 // Xinef: allow entry specific spells to skip those checks
4992 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
4993 {
4995 return;
4996
4997 if (unitTarget->GetVehicle())
4998 return;
4999
5000 if (Creature* creatureTarget = unitTarget->ToCreature())
5001 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
5002 return;
5003 }
5004
5005 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
5007 return;
5008
5009 // Instantly interrupt non melee spells being casted
5012
5013 float ratio = 0.1f;
5014 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
5015 float speedz = float(damage) * ratio;
5016 if (speedxy <= 0.1f && speedz <= 0.1f)
5017 return;
5018
5019 float x, y;
5020 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
5021 {
5022 if (m_targets.HasDst())
5023 destTarget->GetPosition(x, y);
5024 else
5025 return;
5026 }
5027 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5028 {
5029 m_caster->GetPosition(x, y);
5030 }
5031
5032 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5033
5034 if (unitTarget->IsPlayer())
5035 {
5036 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5037 }
5038}
@ SPELL_EFFECT_KNOCK_BACK_DEST
Definition: SharedDefines.h:922
@ CREATURE_TYPE_GIANT
Definition: SharedDefines.h:2632
@ CREATURE_TYPE_BEAST
Definition: SharedDefines.h:2628
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4129
uint32 GetCreatureType() const
Definition: Unit.cpp:15177
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition: Unit.cpp:19139

References CREATURE_TYPE_BEAST, CREATURE_TYPE_GIANT, damage, destTarget, effectHandleMode, SpellInfo::Effects, Unit::GetCreatureType(), Position::GetPosition(), Unit::GetVehicle(), SpellCastTargets::HasDst(), Unit::HasUnitState(), Unit::InterruptNonMeleeSpells(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsVehicle(), Unit::KnockbackFrom(), m_caster, m_spellInfo, m_targets, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_KNOCK_BACK_DEST, sScriptMgr, TARGET_CHECK_ENTRY, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_ROOT, and unitTarget.

◆ EffectLeap()

void Spell::EffectLeap ( SpellEffIndex  effIndex)
4710{
4712 return;
4713
4714 if (!unitTarget || unitTarget->IsInFlight())
4715 return;
4716
4717 if (!m_targets.HasDst())
4718 return;
4719
4720 Position dstpos = destTarget->GetPosition();
4722}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:19975

References destTarget, effectHandleMode, Position::GetOrientation(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellCastTargets::HasDst(), Unit::IsInFlight(), m_caster, m_targets, Unit::NearTeleportTo(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectLeapBack()

void Spell::EffectLeapBack ( SpellEffIndex  effIndex)
5041{
5043 return;
5044
5045 if (!unitTarget)
5046 return;
5047
5048 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5049 float speedz = damage / 10.0f;
5050 //1891: Disengage
5052
5053 if (m_caster->IsPlayer())
5054 {
5055 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
5056 }
5057
5058 // xinef: changes fall time
5059 if (m_caster->IsPlayer())
5061}
@ SPELLFAMILY_HUNTER
Definition: SharedDefines.h:3537
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition: Unit.cpp:19520

References damage, effectHandleMode, SpellInfo::Effects, GameTime::GetGameTime(), Position::GetPositionZ(), Object::IsPlayer(), Unit::JumpTo(), m_caster, m_spellInfo, Player::SetFallInformation(), SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3251{
3253 return;
3254
3255 if (!unitTarget)
3256 return;
3257
3258 if (unitTarget->ToPlayer())
3259 {
3260 EffectLearnSpell(effIndex);
3261 return;
3262 }
3263 Pet* pet = unitTarget->ToPet();
3264 if (!pet)
3265 return;
3266
3267 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3268 if (!learn_spellproto)
3269 return;
3270
3271 pet->learnSpell(learn_spellproto->Id);
3273 pet->GetOwner()->PetSpellInitialize();
3274}
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1912
void EffectLearnSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:2537

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

void Spell::EffectLearnSkill ( SpellEffIndex  effIndex)
2768{
2770 return;
2771
2772 if (!unitTarget->IsPlayer())
2773 return;
2774
2775 if (damage < 0)
2776 return;
2777
2778 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2779 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2780 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2781}
uint16 GetPureSkillValue(uint32 skill) const
Definition: Player.cpp:5510
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5324

References damage, effectHandleMode, SpellInfo::Effects, Player::GetPureSkillValue(), Object::IsPlayer(), m_spellInfo, Player::SetSkill(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectLearnSpell()

void Spell::EffectLearnSpell ( SpellEffIndex  effIndex)
2538{
2540 return;
2541
2542 if (!unitTarget)
2543 return;
2544
2545 if (!unitTarget->IsPlayer())
2546 {
2547 if (unitTarget->ToPet())
2548 EffectLearnPetSpell(effIndex);
2549 return;
2550 }
2551
2552 Player* player = unitTarget->ToPlayer();
2553
2554 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2555 player->learnSpell(spellToLearn);
2556
2557 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2558 player->GetGUID().ToString(), spellToLearn, m_caster->GetGUID().ToString());
2559}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3279
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:3250

References damage, effectHandleMode, EffectLearnPetSpell(), SpellInfo::Effects, Object::GetGUID(), SpellInfo::Id, Object::IsPlayer(), Player::learnSpell(), LOG_DEBUG, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5520{
5522 return;
5523
5524 if (!m_caster->IsPlayer())
5525 return;
5526
5527 Player* p_caster = m_caster->ToPlayer();
5529 return;
5530
5531 if (itemTarget->GetCount() < 5)
5532 return;
5533
5534 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5535 {
5536 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5537 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5538 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5539 }
5540
5542}
@ CONFIG_SKILL_MILLING
Definition: IWorld.h:92
@ LOOT_MILLING
Definition: LootMgr.h:87
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7783
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition: PlayerUpdates.cpp:720

References CONFIG_SKILL_MILLING, effectHandleMode, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_IS_MILLABLE, itemTarget, LOOT_MILLING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_INSCRIPTION, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5353{
5355 return;
5356
5357 if (!unitTarget)
5358 return;
5359
5361}
void ModifyThreatByPercent(Unit *victim, int32 percent)
Definition: ThreatMgr.cpp:508
ThreatMgr & GetThreatMgr()
Definition: Unit.h:903

References damage, effectHandleMode, Unit::GetThreatMgr(), m_caster, ThreatMgr::ModifyThreatByPercent(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectNULL()

void Spell::EffectNULL ( SpellEffIndex  effIndex)
239{
240 LOG_DEBUG("spells.aura", "WORLD: Spell Effect DUMMY");
241}

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

void Spell::EffectOpenLock ( SpellEffIndex  effIndex)
Todo:
: Add script for spell 41920 - Filling, becouse server it freze when use this spell
2082{
2084 return;
2085
2086 if (!m_caster->IsPlayer())
2087 {
2088 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2089 return;
2090 }
2091
2092 Player* player = m_caster->ToPlayer();
2093
2094 uint32 lockId = 0;
2095 ObjectGuid guid;
2096
2097 // Get lockId
2098 if (gameObjTarget)
2099 {
2100 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2101 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2102 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2103 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2104 {
2105 //CanUseBattlegroundObject() already called in CheckCast()
2106 // in battleground check
2107 if (Battleground* bg = player->GetBattleground())
2108 {
2109 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2110 return;
2111 }
2112 }
2113 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2114 {
2115 //CanUseBattlegroundObject() already called in CheckCast()
2116 // in battleground check
2117 if (Battleground* bg = player->GetBattleground())
2118 {
2119 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2120 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2121 return;
2122 }
2123 }
2124 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2125 {
2128 {
2130 }
2131 return;
2132 }
2134 // handle outdoor pvp object opening, return true if go was registered for handling
2135 // these objects must have been spawned by outdoorpvp!
2136 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2137 return;
2138 lockId = goInfo->GetLockId();
2139 guid = gameObjTarget->GetGUID();
2140 }
2141 else if (itemTarget)
2142 {
2143 lockId = itemTarget->GetTemplate()->LockID;
2144 guid = itemTarget->GetGUID();
2145 }
2146 else
2147 {
2148 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2149 return;
2150 }
2151
2152 SkillType skillId = SKILL_NONE;
2153 int32 reqSkillValue = 0;
2154 int32 skillValue;
2155
2156 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2157 if (res != SPELL_CAST_OK)
2158 {
2159 SendCastResult(res);
2160 return;
2161 }
2162
2163 if (gameObjTarget)
2164 SendLoot(guid, LOOT_SKINNING);
2165 else if (itemTarget)
2166 {
2168 if (Player* itemOwner = itemTarget->GetOwner())
2169 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2170 }
2171
2172 // not allow use skill grow at item base open
2173 if (!m_CastItem && skillId != SKILL_NONE)
2174 {
2175 // update skill if really known
2176 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2177 {
2178 if (gameObjTarget)
2179 {
2180 // Allow one skill-up until respawned
2181 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2182 {
2184 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2185 }
2186
2187 }
2188 else if (itemTarget)
2189 {
2190 // Do one skill-up
2191 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2192 }
2193 }
2194 }
2196}
@ GAMEOBJECT_TYPE_BUTTON
Definition: SharedDefines.h:1561
@ GAMEOBJECT_TYPE_FLAGSTAND
Definition: SharedDefines.h:1584
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1570
@ BATTLEGROUND_EY
Definition: SharedDefines.h:3487
@ ITEM_CHANGED
Definition: Item.h:210
@ ITEM_FIELD_FLAG_UNLOCKED
Definition: ItemTemplate.h:111
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:113
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ LOOT_SKINNING
Definition: LootMgr.h:85
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:102
Unit * GetOwner() const
Definition: GameObject.cpp:1238
void AddToSkillupList(ObjectGuid playerGuid)
Definition: GameObject.cpp:3068
bool IsInSkillupList(ObjectGuid playerGuid) const
Definition: GameObject.cpp:3074
LootState getLootState() const
Definition: GameObject.h:224
void SetLootState(LootState s, Unit *unit=nullptr)
Definition: GameObject.cpp:2442
Definition: GameObjectData.h:31
uint32 GetAutoCloseTime() const
Definition: GameObjectData.h:510
struct GameObjectTemplate::@228::@239 goober
uint32 noDamageImmune
Definition: GameObjectData.h:48
struct GameObjectTemplate::@228::@231 button
uint32 losOK
Definition: GameObjectData.h:64
uint32 GetLockId() const
Definition: GameObjectData.h:427
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:714
Definition: Object.h:100
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition: Spell.cpp:5139
void SendLoot(ObjectGuid guid, LootType loottype)
Definition: SpellEffects.cpp:2015

References GameObject::AddToSkillupList(), BATTLEGROUND_EY, GameObjectTemplate::button, CanOpenLock(), effectHandleMode, ExecuteLogEffectOpenLock(), GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_FLAGSTAND, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_TRAP, gameObjTarget, GameObjectTemplate::GetAutoCloseTime(), Player::GetBattleground(), GameObject::GetGOInfo(), Object::GetGUID(), GameObjectTemplate::GetLockId(), GameObject::getLootState(), GameObject::GetOwner(), Item::GetOwner(), Player::GetPureSkillValue(), Item::GetTemplate(), GO_JUST_DEACTIVATED, GameObjectTemplate::goober, SpellInfo::Id, IN_MILLISECONDS, GameObject::IsInSkillupList(), Object::IsPlayer(), ITEM_CHANGED, ITEM_FIELD_FLAG_UNLOCKED, ITEM_FIELD_FLAGS, itemTarget, ItemTemplate::LockID, LOG_DEBUG, LOOT_SKINNING, GameObjectTemplate::losOK, m_caster, m_CastItem, m_spellInfo, GameObjectTemplate::noDamageImmune, SendCastResult(), SendLoot(), Object::SetFlag(), GameObject::SetLootState(), GameObject::SetRespawnTime(), Item::SetState(), SKILL_NONE, sOutdoorPvPMgr, SPELL_CAST_OK, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), GameObjectTemplate::type, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4692{
4694 return;
4695
4696 if (m_caster->IsPlayer())
4697 m_caster->ToPlayer()->SetCanParry(true);
4698}
void SetCanParry(bool value)
Definition: Player.cpp:13135

References effectHandleMode, Object::IsPlayer(), m_caster, Player::SetCanParry(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1845{
1847 return;
1848
1849 if (!m_spellAura)
1850 {
1852 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1853
1854 // Caster not in world, might be spell triggered from aura removal
1855 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1856 return;
1857 DynamicObject* dynObj = new DynamicObject(false);
1858 if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
1859 {
1860 delete dynObj;
1861 return;
1862 }
1863
1865 {
1866 m_spellAura = aura;
1869 }
1870 else
1871 return;
1872 }
1873
1876}
#define MAX_EFFECT_MASK
Definition: DBCStructure.h:1637
@ DYNAMIC_OBJECT_AREA_SPELL
Definition: DynamicObject.h:30
DynamicObject * GetDynobjOwner() const
Definition: SpellAuras.h:109
static Aura * TryCreate(SpellInfo const *spellproto, uint8 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=nullptr, Item *castItem=nullptr, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemGUID=ObjectGuid::Empty)
Definition: SpellAuras.cpp:352

References Aura::_ApplyEffectForTargets(), Aura::_RegisterForTargets(), ASSERT, DynamicObject::CreateDynamicObject(), destTarget, DYNAMIC_OBJECT_AREA_SPELL, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, WorldObject::FindMap(), Map::GenerateLowGuid(), Aura::GetDynobjOwner(), Object::GetEntry(), Object::GetGUID(), WorldObject::GetMap(), ObjectAccessor::GetUnit(), SpellInfo::Id, Object::IsInWorld(), m_caster, m_originalCaster, m_spellAura, m_spellInfo, m_spellValue, m_triggeredByAuraSpell, MAX_EFFECT_MASK, Aura::SetTriggeredByAuraSpellInfo(), SPELL_EFFECT_HANDLE_HIT, TriggeredByAuraSpellData::spellInfo, Aura::TryCreate(), and WORLD_TRIGGER.

◆ EffectPickPocket()

void Spell::EffectPickPocket ( SpellEffIndex  effIndex)

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6106{
6108 return;
6109
6110 if (!unitTarget)
6111 return;
6112
6113 Player* player = unitTarget->ToPlayer();
6114 if (!player)
6115 {
6116 return;
6117 }
6118
6119 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6120
6121 if (!sSoundEntriesStore.LookupEntry(soundid))
6122 {
6123 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6124 return;
6125 }
6126
6128}
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
Definition: MiscPackets.h:58

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, LOG_ERROR, m_spellInfo, Player::SendDirectMessage(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPlaySound()

void Spell::EffectPlaySound ( SpellEffIndex  effIndex)
6159{
6161 return;
6162
6163 if (!unitTarget)
6164 return;
6165
6166 Player* player = unitTarget->ToPlayer();
6167 if (!player)
6168 {
6169 return;
6170 }
6171
6172 switch (m_spellInfo->Id)
6173 {
6174 case 58730: // Restricted Flight Area
6175 case 58600: // Restricted Flight Area
6177 break;
6178 default:
6179 break;
6180 }
6181
6182 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6183
6184 if (!sSoundEntriesStore.LookupEntry(soundId))
6185 {
6186 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6187 return;
6188 }
6189
6190 player->PlayDirectSound(soundId, player);
6191}
@ LANG_ZONE_NOFLYZONE
Definition: Language.h:753
Definition: Chat.h:37
void SendNotification(std::string_view str)
Definition: Chat.cpp:104
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition: Object.cpp:2892

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), SpellInfo::Id, LANG_ZONE_NOFLYZONE, LOG_ERROR, m_spellInfo, WorldObject::PlayDirectSound(), ChatHandler::SendNotification(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSoundEntriesStore, Object::ToPlayer(), and unitTarget.

◆ EffectPowerBurn()

void Spell::EffectPowerBurn ( SpellEffIndex  effIndex)
1431{
1433 return;
1434
1435 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1436 return;
1437
1438 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1439
1441 return;
1442
1443 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1444 if (m_spellInfo->Id == 8129)
1445 {
1448 damage = std::min(damage, maxDamage);
1449
1450 // Remove fear
1452 }
1453
1454 int32 power = damage;
1455 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1456 if (PowerType == POWER_MANA)
1457 power -= unitTarget->GetSpellCritDamageReduction(power);
1458
1459 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1460
1461 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1462 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1463
1464 // add log data before multiplication (need power amount, not damage)
1465 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1466
1467 newDamage = int32(newDamage * dmgMultiplier);
1468
1469 m_damage += newDamage;
1470}
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:14144
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition: Unit.h:1201
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition: Spell.cpp:5108

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_damage, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, Unit::RemoveAurasByType(), SPELL_AURA_MOD_FEAR, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectPowerDrain()

void Spell::EffectPowerDrain ( SpellEffIndex  effIndex)
1352{
1354 return;
1355
1356 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1357 return;
1358
1359 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1360
1362 return;
1363
1364 // add spell damage bonus
1367
1368 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1369 int32 power = damage;
1370 if (PowerType == POWER_MANA)
1371 power -= unitTarget->GetSpellCritDamageReduction(power);
1372
1373 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1374
1375 float gainMultiplier = 0.0f;
1376
1377 // Don`t restore from self drain
1378 if (m_caster != unitTarget)
1379 {
1380 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1381
1382 int32 gain = int32(newDamage * gainMultiplier);
1383
1385 }
1386 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1387}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), m_caster, m_originalCaster, m_spellInfo, MAX_POWERS, Unit::ModifyPower(), POWER_MANA, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectProficiency()

void Spell::EffectProficiency ( SpellEffIndex  effIndex)
2308{
2310 return;
2311
2312 if (!m_caster->IsPlayer())
2313 return;
2314 Player* p_target = m_caster->ToPlayer();
2315
2317 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2318 {
2319 p_target->AddWeaponProficiency(subClassMask);
2321 }
2322 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2323 {
2324 p_target->AddArmorProficiency(subClassMask);
2326 }
2327}
uint32 GetArmorProficiency() const
Definition: Player.h:1355
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition: Player.cpp:10111
uint32 GetWeaponProficiency() const
Definition: Player.h:1354
void AddArmorProficiency(uint32 newflag)
Definition: Player.h:1353
void AddWeaponProficiency(uint32 newflag)
Definition: Player.h:1352
int32 EquippedItemSubClassMask
Definition: SpellInfo.h:376

References Player::AddArmorProficiency(), Player::AddWeaponProficiency(), effectHandleMode, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::GetArmorProficiency(), Player::GetWeaponProficiency(), Object::IsPlayer(), ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, m_caster, m_spellInfo, Player::SendProficiency(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

void Spell::EffectPull ( SpellEffIndex  effIndex)
Todo:
: create a proper pull towards distract spell center for distract
2680{
2682 EffectNULL(effIndex);
2683}
void EffectNULL(SpellEffIndex effIndex)
Definition: SpellEffects.cpp:238

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5126{
5128 return;
5129
5130 if (!unitTarget)
5131 return;
5132
5133 Position pos;
5134 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5135 {
5136 if (m_targets.HasDst())
5137 pos.Relocate(*destTarget);
5138 else
5139 return;
5140 }
5141 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5142 {
5143 // Xinef: Increase Z position a little bit, should protect from falling through textures
5145 }
5146
5147 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5148 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5149
5150 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5151
5152 if (unitTarget->IsPlayer())
5153 {
5154 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5155 }
5156}
@ SPELL_EFFECT_PULL_TOWARDS_DEST
Definition: SharedDefines.h:923
void Relocate(float x, float y)
Definition: Position.h:72

References destTarget, effectHandleMode, SpellInfo::Effects, WorldObject::GetDistance(), Unit::GetMotionMaster(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Movement::gravity, SpellCastTargets::HasDst(), Object::IsPlayer(), m_caster, m_spellInfo, m_targets, MotionMaster::MoveJump(), Position::Relocate(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_PULL_TOWARDS_DEST, sScriptMgr, Object::ToPlayer(), and unitTarget.

◆ EffectQuestClear()

void Spell::EffectQuestClear ( SpellEffIndex  effIndex)
5064{
5066 return;
5067
5068 if (!unitTarget)
5069 return;
5070
5071 Player* player = unitTarget->ToPlayer();
5072 if (!player)
5073 {
5074 return;
5075 }
5076
5077 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5078
5079 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5080
5081 if (!quest)
5082 return;
5083
5084 // Player has never done this quest
5085 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5086 return;
5087
5088 // remove all quest entries for 'entry' from quest log
5089 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5090 {
5091 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5092 if (logQuest == quest_id)
5093 {
5094 player->SetQuestSlot(slot, 0);
5095
5096 // we ignore unequippable quest items in this case, it's still be equipped
5097 player->TakeQuestSourceItem(logQuest, false);
5098
5099 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5100 {
5101 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5102 player->UpdatePvPState();
5103 }
5104 }
5105 }
5106
5107 player->RemoveRewardedQuest(quest_id);
5108 player->RemoveActiveQuest(quest_id, false);
5109}
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
bool IsHostile
Definition: Player.h:360
bool IsInHostileArea
Definition: Player.h:361
bool HasPvPForcingQuest() const
Definition: PlayerQuest.cpp:2494
void UpdatePvPState()
Definition: PlayerUpdates.cpp:1393
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1477
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1481
PvPInfo pvpInfo
Definition: Player.h:1830
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition: PlayerQuest.cpp:1362
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1494
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: PlayerQuest.cpp:1429
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition: PlayerQuest.cpp:1512
Definition: QuestDef.h:210
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:221

References effectHandleMode, SpellInfo::Effects, Player::GetQuestSlotQuestId(), Player::GetQuestStatus(), Quest::HasFlag(), Player::HasPvPForcingQuest(), PvPInfo::IsHostile, PvPInfo::IsInHostileArea, m_spellInfo, MAX_QUEST_LOG_SIZE, Player::pvpInfo, QUEST_FLAGS_FLAGS_PVP, QUEST_STATUS_NONE, Player::RemoveActiveQuest(), Player::RemoveRewardedQuest(), Player::SetQuestSlot(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Player::TakeQuestSourceItem(), Object::ToPlayer(), unitTarget, and Player::UpdatePvPState().

◆ EffectQuestComplete()

void Spell::EffectQuestComplete ( SpellEffIndex  effIndex)
4751{
4753 return;
4754
4755 if (!unitTarget)
4756 return;
4757
4758 Player* player = unitTarget->ToPlayer();
4759 if (!player)
4760 {
4761 return;
4762 }
4763
4764 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4765 if (questId)
4766 {
4767 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4768 if (!quest)
4769 return;
4770
4771 uint16 logSlot = player->FindQuestSlot(questId);
4772 if (logSlot < MAX_QUEST_LOG_SIZE)
4773 player->AreaExploredOrEventHappens(questId);
4774 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
4775 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
4776 }
4777}
uint16 FindQuestSlot(uint32 quest_id) const
Definition: PlayerQuest.cpp:1781
bool CanTakeQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:251
void SetRewardedQuest(uint32 quest_id)
Definition: PlayerQuest.cpp:879
void AreaExploredOrEventHappens(uint32 questId)
Definition: PlayerQuest.cpp:1790

References Player::AreaExploredOrEventHappens(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Player::FindQuestSlot(), m_spellInfo, MAX_QUEST_LOG_SIZE, Player::SetRewardedQuest(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestFail()

void Spell::EffectQuestFail ( SpellEffIndex  effIndex)
5732{
5734 return;
5735
5736 if (!unitTarget)
5737 return;
5738
5739 if (Player* player = unitTarget->ToPlayer())
5740 {
5741 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5742 }
5743}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
5746{
5748 return;
5749
5750 if (!unitTarget)
5751 return;
5752
5753 Player* player = unitTarget->ToPlayer();
5754 if (!player)
5755 return;
5756
5757 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
5758 {
5759 if (!player->CanTakeQuest(quest, false))
5760 return;
5761
5762 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
5763 player->AddQuestAndCheckCompletion(quest, player);
5764
5765 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
5766 }
5767}
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:388
bool CanAddQuest(Quest const *quest, bool msg)
Definition: PlayerQuest.cpp:264
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
Definition: PlayerQuest.cpp:420
PlayerMenu * PlayerTalkClass
Definition: Player.h:2222

References Player::AddQuestAndCheckCompletion(), Player::CanAddQuest(), Player::CanTakeQuest(), effectHandleMode, SpellInfo::Effects, Object::GetGUID(), m_spellInfo, Player::PlayerTalkClass, PlayerMenu::SendQuestGiverQuestDetails(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectRechargeManaGem()

void Spell::EffectRechargeManaGem ( SpellEffIndex  effIndex)
6248{
6250 return;
6251
6252 if (!unitTarget || !unitTarget->IsPlayer())
6253 return;
6254
6255 Player* player = m_caster->ToPlayer();
6256
6257 if (!player)
6258 return;
6259
6260 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6261
6262 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6263 if (!pProto)
6264 {
6265 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6266 return;
6267 }
6268
6269 if (Item* pItem = player->GetItemByEntry(item_id))
6270 {
6271 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6272 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6273 pItem->SetState(ITEM_CHANGED, player);
6274 }
6275}

References EFFECT_0, effectHandleMode, SpellInfo::Effects, EQUIP_ERR_ITEM_NOT_FOUND, Player::GetItemByEntry(), Object::IsPlayer(), ITEM_CHANGED, m_caster, m_spellInfo, MAX_ITEM_PROTO_SPELLS, Player::SendEquipError(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT_TARGET, _Spell::SpellCharges, ItemTemplate::Spells, Object::ToPlayer(), and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
5906{
5908 return;
5909
5910 if (unitTarget)
5912}
void SetRedirectThreat(ObjectGuid guid, uint32 pct)
Definition: Unit.h:910

References damage, effectHandleMode, Object::GetGUID(), m_caster, Unit::SetRedirectThreat(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6194{
6196 return;
6197
6198 if (!unitTarget)
6199 return;
6200 // there may be need of specifying casterguid of removed auras
6201 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6202}

References effectHandleMode, SpellInfo::Effects, m_spellInfo, Unit::RemoveAurasDueToSpell(), SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6094{
6096 return;
6097
6098 if (!unitTarget || !unitTarget->IsCreature() ||
6100 return;
6101
6103}
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
@ UNIT_CAN_BE_RENAMED
Definition: UnitDefines.h:128
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
PetType getPetType() const
Definition: Pet.h:52

References effectHandleMode, Pet::getPetType(), HUNTER_PET, Object::IsCreature(), Unit::IsPet(), Object::SetByteFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), UNIT_CAN_BE_RENAMED, UNIT_FIELD_BYTES_2, and unitTarget.

◆ EffectReputation()

void Spell::EffectReputation ( SpellEffIndex  effIndex)
4725{
4727 return;
4728
4729 if (!unitTarget)
4730 return;
4731
4732 Player* player = unitTarget->ToPlayer();
4733 if (!player)
4734 {
4735 return;
4736 }
4737
4738 float repChange = static_cast<float>(damage);
4739
4740 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4741
4742 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4743 if (!factionEntry)
4744 return;
4745
4746 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4747 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4748}
@ REPUTATION_SOURCE_SPELL
Definition: Player.h:245
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
float CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, float rep, int32 faction, bool noQuestBonus=false)
Definition: Player.cpp:5877
ReputationMgr & GetReputationMgr()
Definition: Player.h:2108
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition: ReputationMgr.h:117
Definition: DBCStructure.h:906

References Player::CalculateReputationGain(), damage, effectHandleMode, SpellInfo::Effects, Player::GetReputationMgr(), m_spellInfo, ReputationMgr::ModifyReputation(), REPUTATION_SOURCE_SPELL, sFactionStore, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrect()

void Spell::EffectResurrect ( SpellEffIndex  effIndex)
4643{
4645 return;
4646
4647 if (!unitTarget)
4648 return;
4649
4650 if (!unitTarget)
4651 return;
4652
4653 Player* target = unitTarget->ToPlayer();
4654 if (!target)
4655 {
4656 return;
4657 }
4658
4659 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4660 return;
4661
4662 if (target->isResurrectRequested()) // already have one active request
4663 return;
4664
4665 uint32 health = target->CountPctFromMaxHealth(damage);
4667
4668 ExecuteLogEffectResurrect(effIndex, target);
4669
4671 SendResurrectRequest(target);
4672}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition: Player.h:1799
bool isResurrectRequested() const
Definition: Player.h:1811
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition: Spell.cpp:5169
void SendResurrectRequest(Player *target)
Definition: Spell.cpp:5231

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Unit::GetMaxPower(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Player::isResurrectRequested(), m_caster, POWER_MANA, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectResurrectNew()

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5202{
5204 return;
5205
5206 if (damage < 0)
5207 return;
5208
5209 Player* player = m_caster->ToPlayer();
5210 if (!player)
5211 {
5212 return;
5213 }
5214
5215 Pet* pet = player->GetPet();
5216 if (!pet)
5217 {
5218 // Position passed to SummonPet is irrelevant with current implementation,
5219 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5220 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0s, damage);
5221 return;
5222 }
5223
5225 if (pet->IsAlive())
5226 {
5227 return;
5228 }
5229
5230 // Reposition the pet's corpse before reviving so as not to grab aggro
5231 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5232 float x, y, z; // Will be used later to reposition the pet if we have one
5233 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5234 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5235 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5238 pet->setDeathState(DeathState::Alive);
5239 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5241 pet->SetDisplayId(pet->GetNativeDisplayId());
5242
5243 // xinef: restore movement
5244 if (auto ci = pet->GetCharmInfo())
5245 {
5246 ci->SetIsAtStay(false);
5247 ci->SetIsFollowing(false);
5248 }
5249
5251}
@ UNIT_DYNFLAG_NONE
Definition: SharedDefines.h:3120
@ UNIT_STATE_POSSESSED
Definition: UnitDefines.h:165
@ UNIT_STATE_ALL_STATE
Definition: UnitDefines.h:199
#define PET_FOLLOW_DIST
Definition: PetDefines.h:198
@ SUMMON_PET
Definition: PetDefines.h:31
float GetFollowAngle() const override
Definition: TemporarySummon.h:82
bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0, WorldObject const *forWho=nullptr, bool force=false) const
Definition: Object.cpp:2699
void setDeathState(DeathState s, bool despawn=false) override
A creature can be in 4 different states: Alive, JustDied, Corpse, and JustRespawned....
Definition: Pet.cpp:631
void SetDisplayId(uint32 modelId, float displayScale=1.f) override
Definition: Pet.cpp:2421
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0s, uint32 healthPct=0)
Definition: Player.cpp:8939
void ReplaceAllDynamicFlags(uint32 flag) override
Definition: Unit.h:731
void SetHealth(uint32 val)
Definition: Unit.cpp:15473
uint32 GetNativeDisplayId() const
Definition: Unit.h:1793
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition: Unit.h:714

References Unit::ClearUnitState(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, Unit::GetCharmInfo(), WorldObject::GetClosePoint(), Unit::GetCombatReach(), Minion::GetFollowAngle(), Unit::GetNativeDisplayId(), Position::GetOrientation(), Player::GetPet(), Unit::IsAlive(), m_caster, Unit::NearTeleportTo(), PET_FOLLOW_DIST, PET_SAVE_AS_CURRENT, Position::Relocate(), Unit::RemoveUnitFlag(), Unit::ReplaceAllDynamicFlags(), Pet::SavePetToDB(), Pet::setDeathState(), Pet::SetDisplayId(), Unit::SetHealth(), SPELL_EFFECT_HANDLE_HIT, SUMMON_PET, Player::SummonPet(), Object::ToPlayer(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4027{
4029 return;
4030
4031 if (!unitTarget)
4032 return;
4033
4035 {
4037 // Xinef: replaced with CombatStop(false)
4040
4041 // Night Elf: Shadowmeld only resets threat temporarily
4042 if (m_spellInfo->Id != 59646)
4044
4045 if (unitTarget->IsPlayer())
4046 unitTarget->ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
4047 }
4048 else
4049 {
4050 unitTarget->getHostileRefMgr().UpdateVisibility(m_spellInfo->Id == 59646); // Night Elf: Shadowmeld
4051 unitTarget->CombatStop(true);
4052 }
4053
4054 UnitList targets;
4055 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4058 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4059 {
4060 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4061 continue;
4062
4064 {
4065 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4066 {
4067 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4068 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4069 {
4070 Creature* c = (*iter)->ToCreature();
4071 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4072 continue;
4073 }
4074 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4075 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4076 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4077 {
4078 // at least one effect truly targets an unit, interrupt the spell
4079 interrupt = true;
4080 break;
4081 }
4082 if (interrupt)
4083 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4084 }
4085 }
4086 }
4087
4088 // Xinef: Set last sanctuary time
4090}
#define CURRENT_MAX_SPELL
Definition: Unit.h:544
void UpdateVisibility(bool checkThreat)
Definition: HostileRefMgr.cpp:236
void addThreatPercent(int32 percent)
Definition: HostileRefMgr.cpp:85
void SendAttackSwingCancelAttack()
Definition: PlayerMisc.cpp:140
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10436
void RemoveAllAttackers()
Remove all units in m_attackers list and send them AttackStop()
Definition: Unit.cpp:10484
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition: Unit.cpp:10403
virtual bool IsEncounterInProgress() const
Definition: InstanceScript.cpp:125

References HostileRefMgr::addThreatPercent(), Unit::AttackStop(), Unit::CombatStop(), CREATURE_ELITE_WORLDBOSS, CURRENT_FIRST_NON_MELEE_SPELL, CURRENT_MAX_SPELL, effectHandleMode, SpellInfo::Effects, Creature::GetCreatureTemplate(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::getHostileRefMgr(), WorldObject::GetInstanceScript(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::InterruptSpell(), Creature::IsDungeonBoss(), InstanceScript::IsEncounterInProgress(), Unit::IsPet(), Object::IsPlayer(), Creature::isWorldBoss(), Unit::m_lastSanctuaryTime, m_spellInfo, MAX_SPELL_EFFECTS, CreatureTemplate::rank, Unit::RemoveAllAttackers(), Player::SendAttackSwingCancelAttack(), SPELL_ATTR6_IGNORE_PHASE_SHIFT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST, Object::ToCreature(), Object::ToPlayer(), UNIT_STATE_CASTING, unitTarget, HostileRefMgr::UpdateVisibility(), and Cell::VisitAllObjects().

◆ EffectSchoolDMG()

void Spell::EffectSchoolDMG ( SpellEffIndex  effIndex)
Todo:
: should this be put on taken but not done?
324{
326 return;
327
328 if (unitTarget && unitTarget->IsAlive())
329 {
330 bool apply_direct_bonus = true;
332 {
334 {
335 // Meteor like spells (divided damage to targets)
337 {
338 uint32 count = 0;
339 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
340 if (ihit->effectMask & (1 << effIndex))
341 ++count;
342
343 damage /= count; // divide to all targets
344 }
345 break;
346 }
348 {
349 // Shield Slam
350 if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
351 {
352 uint8 level = m_caster->GetLevel();
353 // xinef: shield block should increase the limit
354 float limit = m_caster->HasAura(2565) ? 2.0f : 1.0f;
355 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f * limit), uint32(float(level) * 34.5f * limit));
356
357 damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
358 }
359 // Victory Rush
360 else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
362 // Shockwave
363 else if (m_spellInfo->Id == 46968)
364 {
366 if (pct > 0)
368 break;
369 }
370 break;
371 }
373 {
374 // Incinerate Rank 1 & 2
375 if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
376 {
377 // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
378 // Check aura state for speed but aura state set not only for Immolate spell
380 {
382 damage += damage / 4;
383 }
384 }
385 // Conflagrate - consumes Immolate or Shadowflame
387 {
388 AuraEffect const* aura = nullptr; // found req. aura for damage calculation
389
391 for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
392 {
393 // for caster applied auras only
394 if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
395 (*i)->GetCasterGUID() != m_caster->GetGUID())
396 continue;
397
398 // Immolate
399 if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
400 {
401 aura = *i; // it selected always if exist
402 break;
403 }
404
405 // Shadowflame
406 if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
407 aura = *i; // remember but wait possible Immolate as primary priority
408 }
409
410 // found Immolate or Shadowflame
411 if (aura)
412 {
413 uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
414 pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
415 uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
416 uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
417
418 damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
419
420 uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
421 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
422
423 apply_direct_bonus = false;
424 // Glyph of Conflagrate
425 if (!m_caster->HasAura(56235))
427
428 break;
429 }
430 }
431 // Shadow Bite
432 else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
433 {
434 if (m_caster->IsCreature() && m_caster->IsPet())
435 {
436 if (Player* owner = m_caster->GetOwner()->ToPlayer())
437 {
438 if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
439 {
440 int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
441 m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true);
442 }
443 }
444 }
445 }
446 break;
447 }
449 {
450 // Improved Mind Blast (Mind Blast in shadow form bonus)
451 if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
452 {
454 for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
455 {
456 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
457 ((*i)->GetSpellInfo()->SpellIconID == 95))
458 {
459 int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
460 if (roll_chance_i(chance))
461 // Mind Trauma
462 m_caster->CastSpell(unitTarget, 48301, true, 0);
463 break;
464 }
465 }
466 }
467 break;
468 }
470 {
471 // Ferocious Bite
472 if (m_caster->IsPlayer() && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
473 {
474 // converts each extra point of energy into ($f1+$AP/410) additional damage
476 float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
477 int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
478 damage += int32(energy * multiple);
480 }
481 // Wrath
482 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
483 {
484 // Improved Insect Swarm
485 if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
487 AddPct(damage, aurEff->GetAmount());
488 }
489 break;
490 }
492 {
493 // Envenom
494 if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
495 {
496 if (Player* player = m_caster->ToPlayer())
497 {
498 // consume from stack dozes not more that have combo-points
499 if (uint32 combo = player->GetComboPoints())
500 {
501 // Lookup for Deadly poison (only attacker applied)
503 {
504 // count consumed deadly poison doses at target
505 bool needConsume = true;
506 uint32 spellId = aurEff->GetId();
507
508 uint32 doses = aurEff->GetBase()->GetStackAmount();
509 if (doses > combo)
510 doses = combo;
511
512 // Master Poisoner
513 Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
514 for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
515 {
516 if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
517 {
518 uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
519
520 if (chance && roll_chance_i(chance))
521 needConsume = false;
522
523 break;
524 }
525 }
526
527 if (needConsume)
528 for (uint32 i = 0; i < doses; ++i)
530
531 damage *= doses;
532 damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
533 }
534
535 // Eviscerate and Envenom Bonus Damage (item set effect)
536 if (m_caster->HasAura(37169))
537 damage += combo * 40;
538 }
539 }
540 }
541 // Eviscerate
542 else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
543 {
544 if (m_caster->IsPlayer())
545 {
546 if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
547 {
549 damage += int32(ap * combo * 0.07f);
550
551 // Eviscerate and Envenom Bonus Damage (item set effect)
552 if (m_caster->HasAura(37169))
553 damage += combo * 40;
554 }
555 }
556 }
557 break;
558 }
560 {
561 //Gore
562 if (m_spellInfo->SpellIconID == 1578)
563 {
564 if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
565 damage *= 2;
566 }
567 // Steady Shot
568 else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
569 {
570 bool found = false;
571 // check dazed affect
573 for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
574 {
575 if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
576 {
577 found = true;
578 break;
579 }
580 }
581
583 if (found)
584 damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
585
586 if (Player* caster = m_caster->ToPlayer())
587 {
588 // Add Ammo and Weapon damage plus RAP * 0.1
589 float dmg_min = 0.f;
590 float dmg_max = 0.f;
591 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
592 {
593 dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
594 dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
595 }
596
597 if (dmg_max == 0.0f && dmg_min > dmg_max)
598 {
599 damage += int32(dmg_min);
600 }
601 else
602 {
603 damage += irand(int32(dmg_min), int32(dmg_max));
604 }
605 damage += int32(caster->GetAmmoDPS() * caster->GetAttackTime(RANGED_ATTACK) * 0.001f);
606 }
607 }
608 break;
609 }
611 {
612 // Hammer of the Righteous
613 if (m_spellInfo->SpellFamilyFlags[1] & 0x00040000)
614 {
615 // Add main hand dps * effect[2] amount
616 if (Player* player = m_caster->ToPlayer())
617 {
618 float minTotal = 0.f;
619 float maxTotal = 0.f;
620 for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
621 {
622 float tmpMin, tmpMax;
623 player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
624 minTotal += tmpMin;
625 maxTotal += tmpMax;
626 }
627
628 float average = (minTotal + maxTotal) / 2;
631 }
632 break;
633 }
634 // Shield of Righteousness
635 if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
636 {
637 uint8 level = m_caster->GetLevel();
638 uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 34.5f));
639 if (m_caster->GetAuraEffect(64882, EFFECT_0))
640 block_value += 225;
641 damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
642 break;
643 }
644 break;
645 }
646 }
647
648 if (m_originalCaster /*&& damage > 0 Xinef: this can be increased from 0*/ && apply_direct_bonus)
649 {
650 // Xinef: protection
651 if (damage < 0)
652 damage = 0;
653
656 }
657
658 m_damage += damage;
659 }
660}
@ EFFECT_2
Definition: SharedDefines.h:33
@ POWER_ENERGY
Definition: SharedDefines.h:272
@ SPELLFAMILY_PRIEST
Definition: SharedDefines.h:3534
@ AURA_STATE_CONFLAGRATE
Definition: SharedDefines.h:1306
@ SPELL_ATTR0_CU_SHARE_DAMAGE
Definition: SpellInfo.h:179
@ SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK
Definition: SpellAuraDefines.h:309
@ SPELL_AURA_PERIODIC_DAMAGE
Definition: SpellAuraDefines.h:66
@ SPELL_AURA_ADD_FLAT_MODIFIER
Definition: SpellAuraDefines.h:170
@ SPELL_AURA_MOD_DECREASE_SPEED
Definition: SpellAuraDefines.h:96
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:613
@ MINDAMAGE
Definition: Unit.h:135
@ MAXDAMAGE
Definition: Unit.h:136
@ FORM_SHADOW
Definition: UnitDefines.h:95
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition: Unit.cpp:15423
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition: Unit.cpp:14824
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4925
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.h:864
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition: Unit.h:1358
uint8 GetStackAmount() const
Definition: SpellAuras.h:148

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, Unit::CalcSpellDuration(), CalculatePct(), Unit::CalculateSpellDamage(), Unit::CastCustomSpell(), Unit::CastSpell(), damage, DOT, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, effectHandleMode, SpellInfo::Effects, FORM_SHADOW, AuraEffect::GetAmount(), Unit::GetAttackTime(), Unit::GetAuraEffect(), Unit::GetAuraEffectsByType(), AuraEffect::GetBase(), SpellInfo::GetCategory(), Unit::GetComboPoints(), Unit::GetDummyAuraEffect(), Object::GetGUID(), AuraEffect::GetId(), Unit::GetLevel(), Unit::GetOwner(), Unit::GetShapeshiftForm(), Unit::GetShieldBlockValue(), AuraEffect::GetSpellInfo(), Aura::GetStackAmount(), Unit::GetTotalAttackPowerValue(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_damage, m_originalCaster, m_spellInfo, m_spellValue, m_UniqueTargetInfo, MAX_ITEM_PROTO_DAMAGES, MAXDAMAGE, MINDAMAGE, Unit::ModifyPower(), POWER_ENERGY, RANGED_ATTACK, Unit::RemoveAuraFromStack(), Unit::RemoveAurasDueToSpell(), roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_AURA_PERIODIC_DAMAGE, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_PRIEST, SPELLFAMILY_ROGUE, SPELLFAMILY_WARLOCK, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, SpellInfo::SpellVisual, SpellInfo::TargetAuraState, Object::ToPlayer(), and unitTarget.

◆ EffectScriptEffect()

void Spell::EffectScriptEffect ( SpellEffIndex  effIndex)
Todo:
: we must implement hunter pet summon at login there (spell 6962)
3791{
3793 return;
3794
3796
3798 {
3800 {
3801 switch (m_spellInfo->Id)
3802 {
3803 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
3804 case 22539:
3805 case 22972:
3806 case 22975:
3807 case 22976:
3808 case 22977:
3809 case 22978:
3810 case 22979:
3811 case 22980:
3812 case 22981:
3813 case 22982:
3814 case 22983:
3815 case 22984:
3816 case 22985:
3817 {
3818 if (!unitTarget || !unitTarget->IsAlive())
3819 return;
3820
3821 // Onyxia Scale Cloak
3822 if (unitTarget->HasAura(22683))
3823 return;
3824
3825 // Shadow Flame
3826 m_caster->CastSpell(unitTarget, 22682, true);
3827 return;
3828 }
3829 // Plant Warmaul Ogre Banner
3830 case 32307:
3831 if (Player* caster = m_caster->ToPlayer())
3832 {
3833 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
3834 if (Creature* target = unitTarget->ToCreature())
3835 {
3836 target->setDeathState(DeathState::Corpse);
3837 target->RemoveCorpse();
3838 }
3839 }
3840 break;
3841 // SOTA defender teleport
3842 case 54640:
3843 {
3844 if (Player* player = unitTarget->ToPlayer())
3845 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
3846 {
3847 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
3848 {
3849 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
3850 bg->DefendersPortalTeleport(dportal, player);
3851 }
3852 }
3853 return;
3854 }
3855 /*// Mug Transformation
3856 case 41931:
3857 {
3858 if (!m_caster->IsPlayer())
3859 return;
3860
3861 uint8 bag = 19;
3862 uint8 slot = 0;
3863 Item* item = nullptr;
3864
3865 while (bag) // 256 = 0 due to var type
3866 {
3867 item = m_caster->ToPlayer()->GetItemByPos(bag, slot);
3868 if (item && item->GetEntry() == 38587)
3869 break;
3870
3871 ++slot;
3872 if (slot == 39)
3873 {
3874 slot = 0;
3875 ++bag;
3876 }
3877 }
3878 if (bag)
3879 {
3880 if (m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) m_caster->ToPlayer()->RemoveItem(bag, slot, true);
3881 else m_caster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(m_caster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
3882 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
3883 m_caster->CastSpell(m_caster, 42518, true);
3884 return;
3885 }
3886 break;
3887 }*/
3888 // Roll Dice - Decahedral Dwarven Dice
3889 case 47770:
3890 {
3891 char buf[128];
3892 const char* gender = "his";
3893 if (m_caster->getGender() > 0)
3894 gender = "her";
3895 snprintf(buf, sizeof(buf), "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
3896 m_caster->TextEmote(buf);
3897 break;
3898 }
3899 case 52173: // Coyote Spirit Despawn
3900 case 60243: // Blood Parrot Despawn
3903 return;
3904 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
3905 {
3907 return;
3908
3910
3911 return;
3912 }
3913 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
3914 {
3915 if (!m_caster->IsPlayer())
3916 return;
3917
3918 // Delete item from inventory at death
3920
3921 return;
3922 }
3923 case 58418: // Portal to Orgrimmar
3924 case 58420: // Portal to Stormwind
3925 {
3926 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
3927 return;
3928
3929 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
3930 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
3931
3933 unitTarget->CastSpell(unitTarget, spellID, true);
3934
3935 return;
3936 }
3937 // Stoneclaw Totem
3938 case 55328: // Rank 1
3939 case 55329: // Rank 2
3940 case 55330: // Rank 3
3941 case 55332: // Rank 4
3942 case 55333: // Rank 5
3943 case 55335: // Rank 6
3944 case 55278: // Rank 7
3945 case 58589: // Rank 8
3946 case 58590: // Rank 9
3947 case 58591: // Rank 10
3948 {
3949 int32 basepoints0 = damage;
3950 // Cast Absorb on totems
3951 for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)
3952 {
3953 if (!unitTarget->m_SummonSlot[slot])
3954 continue;
3955
3957 if (totem && totem->IsTotem())
3958 {
3959 m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true);
3960 }
3961 }
3962 // Glyph of Stoneclaw Totem
3963 if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0))
3964 {
3965 basepoints0 *= aur->GetAmount();
3966 m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true);
3967 }
3968 break;
3969 }
3970 case 61263: // for item Intravenous Healing Potion (44698)
3971 {
3972 if (!m_caster || !unitTarget)
3973 return;
3974
3975 m_caster->CastSpell(m_caster, 61267, true);
3976 m_caster->CastSpell(m_caster, 61268, true);
3977 return;
3978 }
3979 }
3980 break;
3981 }
3982 case SPELLFAMILY_ROGUE:
3983 {
3984 switch (m_spellInfo->Id)
3985 {
3986 // Master of Subtlety
3987 case 31666:
3988 {
3989 if (!unitTarget)
3990 return;
3991
3992 Aura* mos = unitTarget->GetAura(31665);
3993 if (mos)
3994 {
3995 mos->SetMaxDuration(6000);
3996 mos->SetDuration(6000, true);
3997 }
3998
3999 break;
4000 }
4001 // Overkill
4002 case 58428:
4003 {
4004 if (!unitTarget)
4005 return;
4006
4007 Aura* overkill = unitTarget->GetAura(58427);
4008 if (overkill)
4009 {
4010 overkill->SetMaxDuration(20000);
4011 overkill->SetDuration(20000, true);
4012 }
4013
4014 break;
4015 }
4016 }
4017 break;
4018 }
4019 }
4020
4021 // normal DB scripted effect
4022 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4024}
@ BATTLEGROUND_SA
Definition: SharedDefines.h:3489
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:101
Class for manage Strand of Ancient battleground.
Definition: BattlegroundSA.h:456
void DefendersPortalTeleport(GameObject *portal, Player *plr)
Definition: BattlegroundSA.cpp:585
void DespawnOrUnsummon(Milliseconds msTimeToDespawn, Seconds forcedRespawnTimer)
Definition: Creature.cpp:2176
virtual void UnSummon(uint32 msTime=0)
Definition: TemporarySummon.cpp:282
GameObject * FindNearestGameObject(uint32 entry, float range, bool onlySpawned=false) const
Definition: Object.cpp:2455
std::string const & GetName() const
Definition: Object.h:458
uint8 getGender() const
Definition: Unit.h:805
bool IsSummon() const
Definition: Unit.h:751
virtual void TextEmote(std::string_view text, WorldObject const *target=nullptr, bool isBossEmote=false)
Definition: Unit.cpp:21145

References BATTLEGROUND_SA, Unit::CastCustomSpell(), Unit::CastSpell(), damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), Unit::GetAuraEffect(), Map::GetCreature(), Unit::getGender(), WorldObject::GetMap(), WorldObject::GetName(), Player::GetQuestStatus(), Unit::HasAura(), SpellInfo::Id, Unit::IsAlive(), Object::IsCreature(), Object::IsPlayer(), Unit::IsSummon(), Unit::IsTotem(), LOG_DEBUG, m_caster, m_spellInfo, Unit::m_SummonSlot, MAX_TOTEM_SLOT, QUEST_STATUS_COMPLETE, Map::ScriptsStart(), Aura::SetDuration(), Aura::SetMaxDuration(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SPELLFAMILY_ROGUE, SpellInfo::SpellFamilyName, sSpellScripts, SUMMON_SLOT_TOTEM, Unit::TextEmote(), Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, TempSummon::UnSummon(), and urand().

◆ EffectSelfResurrect()

void Spell::EffectSelfResurrect ( SpellEffIndex  effIndex)
4853{
4855 return;
4856
4857 if (!m_caster || m_caster->IsAlive())
4858 return;
4859 if (!m_caster->IsPlayer())
4860 return;
4861 if (!m_caster->IsInWorld())
4862 return;
4863
4864 uint32 health = 0;
4865 uint32 mana = 0;
4866
4867 // flat case
4868 if (damage < 0)
4869 {
4870 health = uint32(-damage);
4871 mana = m_spellInfo->Effects[effIndex].MiscValue;
4872 }
4873 // percent case
4874 else
4875 {
4879 }
4880
4881 Player* player = m_caster->ToPlayer();
4882 player->ResurrectPlayer(0.0f);
4883
4884 player->SetHealth(health);
4885 player->SetPower(POWER_MANA, mana);
4886 player->SetPower(POWER_RAGE, 0);
4887 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
4888
4889 player->SpawnCorpseBones();
4890}
@ POWER_RAGE
Definition: SharedDefines.h:270
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4680
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4467
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition: Unit.cpp:15561

References CalculatePct(), Unit::CountPctFromMaxHealth(), damage, effectHandleMode, SpellInfo::Effects, Unit::GetMaxPower(), Unit::IsAlive(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_spellInfo, POWER_ENERGY, POWER_MANA, POWER_RAGE, Player::ResurrectPlayer(), Unit::SetHealth(), Unit::SetPower(), Player::SpawnCorpseBones(), SPELL_EFFECT_HANDLE_HIT, and Object::ToPlayer().

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1390{
1391 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1394 return;
1395
1396 WorldObject* target = nullptr;
1397
1398 // call events for object target if present
1400 {
1401 if (unitTarget)
1402 target = unitTarget;
1403 else if (gameObjTarget)
1404 target = gameObjTarget;
1405 }
1406 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1407 {
1408 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1409 // this check was requested by scripters, but it has some downsides:
1410 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1411 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1412 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1413 return;
1414 // some spells have no target entries in dbc and they use focus target
1415 if (focusObject)
1416 target = focusObject;
1418 }
1419
1420 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1421
1422 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1423 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1424 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1425 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1426
1427 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1428}
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:60
@ TARGET_FLAG_UNIT_MASK
Definition: SpellInfo.h:68
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition: SpellInfo.h:70
Definition: Object.h:405
ZoneScript * GetZoneScript() const
Definition: Object.h:537
Definition: ZoneScript.h:26

References effectHandleMode, SpellInfo::Effects, focusObject, gameObjTarget, WorldObject::GetInstanceScript(), WorldObject::GetMap(), WorldObject::GetZoneScript(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, Map::ScriptsStart(), sEventScripts, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_UNIT_MASK, and unitTarget.

◆ EffectSendTaxi()

void Spell::EffectSendTaxi ( SpellEffIndex  effIndex)
5112{
5114 return;
5115
5116 if (!unitTarget)
5117 return;
5118
5119 if (Player* player = unitTarget->ToPlayer())
5120 {
5121 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5122 }
5123}

References effectHandleMode, SpellInfo::Effects, SpellInfo::Id, m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5545{
5547 return;
5548
5549 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5550}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
4893{
4895 return;
4896
4897 if (!unitTarget->IsCreature())
4898 return;
4899 if (!m_caster->IsPlayer())
4900 return;
4901
4902 Creature* creature = unitTarget->ToCreature();
4903 int32 targetLevel = creature->GetLevel();
4904
4905 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4906
4910
4911 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
4912
4913 int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
4914
4915 // Double chances for elites
4916 m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
4917}
@ UNIT_DYNFLAG_LOOTABLE
Definition: SharedDefines.h:3121
bool isElite() const
Definition: Creature.h:111
virtual void SetDynamicFlag(uint32 flag)
Definition: Object.h:120

References effectHandleMode, Creature::GetCreatureTemplate(), Object::GetGUID(), Unit::GetLevel(), Player::GetPureSkillValue(), CreatureTemplate::GetRequiredLootSkill(), Object::IsCreature(), Creature::isElite(), Object::IsPlayer(), LOOT_SKINNING, m_caster, Unit::RemoveUnitFlag(), Player::SendLoot(), Object::SetDynamicFlag(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5576{
5578 return;
5579
5580 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5581 if ((!m_caster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5582 return;
5583
5585}
void RemovedInsignia(Player *looterPlr)
Definition: Player.cpp:7744

References effectHandleMode, Unit::IsAlive(), Object::IsPlayer(), LOG_DEBUG, m_caster, Player::RemovedInsignia(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6131{
6133 return;
6134
6135 if (!unitTarget)
6136 return;
6137
6138 if (Player* player = unitTarget->ToPlayer())
6139 {
6140 player->UpdateSpecCount(damage);
6141 }
6142}

References damage, effectHandleMode, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5557{
5559 return;
5560
5561 /*
5562 if (!unitTarget->IsPlayer())
5563 return;
5564 if (!unitTarget->IsInWorld())
5565 return;
5566
5567 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5568 //unitTarget->ToPlayer()->setResurrect(m_caster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5569 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5570 unitTarget->ToPlayer()->SpawnCorpseBones();
5571 */
5572}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5588{
5590 return;
5591
5592 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5593
5594 if (!unitTarget || unitTarget == m_caster) // can't steal from self
5595 return;
5596
5597 DispelChargesList steal_list;
5598
5599 // Create dispel mask by dispel type
5600 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5601 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5602 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5603 {
5604 Aura* aura = itr->second;
5606 if (!aurApp)
5607 continue;
5608
5609 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5610 {
5611 // Need check for passive? this
5612 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5613 continue;
5614
5615 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5616 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5617 // Polymorph instead of 1 / (5 + 1) -> 16%.
5618 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5619 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5620 if (charges > 0)
5621 steal_list.push_back(std::make_pair(aura, charges));
5622 }
5623 }
5624
5625 if (steal_list.empty())
5626 return;
5627
5628 // Ok if exist some buffs for dispel try dispel it
5629 uint32 failCount = 0;
5630 DispelList success_list;
5631 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5632 // dispel N = damage buffs (or while exist buffs for dispel)
5633 for (int32 count = 0; count < damage && !steal_list.empty();)
5634 {
5635 // Random select buff for dispel
5636 DispelChargesList::iterator itr = steal_list.begin();
5637 std::advance(itr, urand(0, steal_list.size() - 1));
5638
5639 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(m_caster));
5640 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5641 if (!chance)
5642 {
5643 steal_list.erase(itr);
5644 continue;
5645 }
5646 else
5647 {
5648 if (roll_chance_i(chance))
5649 {
5650 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5651 --itr->second;
5652 if (itr->second <= 0)
5653 steal_list.erase(itr);
5654 }
5655 else
5656 {
5657 if (!failCount)
5658 {
5659 // Failed to dispell
5660 dataFail << m_caster->GetGUID(); // Caster GUID
5661 dataFail << unitTarget->GetGUID(); // Victim GUID
5662 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5663 }
5664 ++failCount;
5665 dataFail << uint32(itr->first->GetId()); // Spell Id
5666 }
5667 ++count;
5668 }
5669 }
5670
5671 if (failCount)
5672 m_caster->SendMessageToSet(&dataFail, true);
5673
5674 if (success_list.empty())
5675 return;
5676
5677 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5678 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5679 dataSuccess << m_caster->GetPackGUID(); // Caster GUID
5680 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5681 dataSuccess << uint8(0); // not used
5682 dataSuccess << uint32(success_list.size()); // count
5683 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5684 {
5685 dataSuccess << uint32(itr->first); // Spell Id
5686 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5687 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
5688 }
5689 m_caster->SendMessageToSet(&dataSuccess, true);
5690}
@ SPELL_ATTR7_DISPEL_REMOVES_CHARGES
Definition: SharedDefines.h:651
@ SPELL_ATTR4_CANNOT_BE_STOLEN
Definition: SharedDefines.h:536
std::list< std::pair< uint32, ObjectGuid > > DispelList
Definition: SpellEffects.cpp:2561
@ SMSG_SPELLSTEALLOG
Definition: Opcodes.h:849
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition: Unit.cpp:5006
bool IsPositive() const
Definition: SpellAuras.h:68
uint8 GetCharges() const
Definition: SpellAuras.h:141
bool IsPassive() const
Definition: SpellAuras.cpp:1082

References damage, effectHandleMode, SpellInfo::Effects, Aura::GetApplicationOfTarget(), Aura::GetCharges(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwnedAuras(), Object::GetPackGUID(), Aura::GetSpellInfo(), Aura::GetStackAmount(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsFriendlyTo(), Aura::IsPassive(), AuraApplication::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellBySteal(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLSTEALLOG, SPELL_ATTR4_CANNOT_BE_STOLEN, SPELL_ATTR7_DISPEL_REMOVES_CHARGES, SPELL_EFFECT_HANDLE_HIT_TARGET, unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4184{
4186 return;
4187
4188 if (!m_caster->IsPlayer())
4189 return;
4190
4191 Player* target = m_caster->ToPlayer();
4192 if (target->IsInFlight())
4193 return;
4194
4195 // xinef: if player is dead - teleport to graveyard
4196 if (!target->IsAlive())
4197 {
4199 return;
4200
4201 // xinef: player is in corpse
4202 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4203 target->BuildPlayerRepop();
4204 target->RepopAtGraveyard();
4205 return;
4206 }
4207
4208 // xinef: no hearthstone in bag or on cooldown
4209 Item* hearthStone = target->GetItemByEntry(6948);
4210 if (!hearthStone || target->HasSpellCooldown(8690))
4211 {
4212 float o = rand_norm() * 2 * M_PI;
4213 Position pos = *target;
4214 target->MovePositionToFirstCollision(pos, 5.0f, o);
4215 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4216 return;
4217 }
4218
4219 // xinef: we have hearthstone not on cooldown, just use it
4221}
double rand_norm()
Definition: Random.cpp:77
@ SPELL_AURA_PREVENT_RESURRECTION
Definition: SpellAuraDefines.h:377
@ PLAYER_FLAGS_GHOST
Definition: Player.h:478
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2860
void RepopAtGraveyard()
Definition: Player.cpp:4914
void BuildPlayerRepop()
Definition: Player.cpp:4418

References Player::BuildPlayerRepop(), Unit::CastSpell(), effectHandleMode, Player::GetItemByEntry(), Position::GetOrientation(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::HasAuraType(), Player::HasPlayerFlag(), Player::HasSpellCooldown(), Unit::IsAlive(), Unit::IsInFlight(), Object::IsPlayer(), m_caster, WorldObject::MovePositionToFirstCollision(), Unit::NearTeleportTo(), PLAYER_FLAGS_GHOST, rand_norm(), Player::RepopAtGraveyard(), SPELL_AURA_PREVENT_RESURRECTION, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), TRIGGERED_FULL_MASK, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2199{
2201 return;
2202
2203 if (!m_caster->IsPlayer())
2204 return;
2205
2206 Player* player = m_caster->ToPlayer();
2207
2208 // applied only to using item
2209 if (!m_CastItem)
2210 return;
2211
2212 // ... only to item in own inventory/bank/equip_slot
2213 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2214 return;
2215
2216 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2217 if (!newitemid)
2218 return;
2219
2220 uint16 pos = m_CastItem->GetPos();
2221
2222 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2223 if (!pNewItem)
2224 return;
2225
2226 // Client-side enchantment durations update
2228
2232
2234 {
2236 player->DurabilityLoss(pNewItem, lossPercent);
2237 }
2238
2239 if (player->IsInventoryPos(pos))
2240 {
2241 ItemPosCountVec dest;
2242 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2243 if (msg == EQUIP_ERR_OK)
2244 {
2245 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2246
2247 // prevent crash at access and unexpected charges counting with item update queue corrupt
2249 m_targets.SetItemTarget(nullptr);
2250
2251 m_CastItem = nullptr;
2253
2254 player->StoreItem(dest, pNewItem, true);
2255 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2256 return;
2257 }
2258 }
2259 else if (player->IsBankPos(pos))
2260 {
2261 ItemPosCountVec dest;
2262 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2263 if (msg == EQUIP_ERR_OK)
2264 {
2265 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2266
2267 // prevent crash at access and unexpected charges counting with item update queue corrupt
2269 m_targets.SetItemTarget(nullptr);
2270
2271 m_CastItem = nullptr;
2273
2274 player->BankItem(dest, pNewItem, true);
2275 return;
2276 }
2277 }
2278 else if (player->IsEquipmentPos(pos))
2279 {
2280 uint16 dest;
2281
2282 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2283
2284 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2285
2286 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2287 {
2289
2290 // prevent crash at access and unexpected charges counting with item update queue corrupt
2292 m_targets.SetItemTarget(nullptr);
2293
2294 m_CastItem = nullptr;
2296
2297 player->EquipItem(dest, pNewItem, true);
2298 player->AutoUnequipOffhandIfNeed();
2299 return;
2300 }
2301 }
2302
2303 // fail
2304 delete pNewItem;
2305}
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:86
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
uint8 GetSlot() const
Definition: Item.h:281
static Item * CreateItem(uint32 item, uint32 count, Player const *player=nullptr, bool clone=false, uint32 randomPropertyId=0)
Definition: Item.cpp:1087
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:305
uint16 GetPos() const
Definition: Item.h:285
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:306
uint8 GetBagSlot() const
Definition: Item.cpp:784
void Clear()
Definition: ObjectGuid.h:138
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1258
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:1805
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1327
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1278
void UpdateEnchantmentDurations()
Definition: PlayerStorage.cpp:4734
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2574
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: PlayerStorage.cpp:3023
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1256
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12470
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition: PlayerStorage.cpp:2727
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
Definition: PlayerStorage.cpp:2032
void ItemAddedQuestCheck(uint32 entry, uint32 count)
Definition: PlayerQuest.cpp:1834
static bool IsBankPos(uint16 pos)
Definition: Player.h:1261

References Player::AutoUnequipOffhandIfNeed(), Player::BankItem(), Player::CanBankItem(), Player::CanEquipItem(), Player::CanStoreItem(), ObjectGuid::Clear(), Item::CreateItem(), Player::DestroyItem(), Player::DurabilityLoss(), effectHandleMode, SpellInfo::Effects, EQUIP_ERR_CANT_DO_RIGHT_NOW, EQUIP_ERR_OK, Player::EquipItem(), EQUIPMENT_SLOT_MAINHAND, Item::GetBagSlot(), Item::GetEnchantmentCharges(), Item::GetEnchantmentDuration(), Item::GetEnchantmentId(), Object::GetEntry(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetOwnerGUID(), Item::GetPos(), Item::GetSlot(), Object::GetUInt32Value(), Player::IsBankPos(), Player::IsEquipmentPos(), Player::IsInventoryPos(), Object::IsPlayer(), ITEM_FIELD_DURABILITY, ITEM_FIELD_MAXDURABILITY, Player::ItemAddedQuestCheck(), m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, PERM_ENCHANTMENT_SLOT, Item::SetEnchantment(), SpellCastTargets::SetItemTarget(), SPELL_EFFECT_HANDLE_HIT, Player::StoreItem(), TEMP_ENCHANTMENT_SLOT, Object::ToPlayer(), and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4571{
4573 return;
4574
4575 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4576
4577 uint8 slot = 0;
4578 switch (m_spellInfo->Effects[effIndex].Effect)
4579 {
4581 slot = 0;
4582 break;
4584 slot = 1;
4585 break;
4587 slot = 2;
4588 break;
4590 slot = 3;
4591 break;
4592 default:
4593 return;
4594 }
4595
4596 if (m_caster)
4597 {
4598 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4599 if (guid)
4600 {
4601 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4602 {
4603 // Recast case - null spell id to make auras not be removed on object remove from world
4604 if (m_spellInfo->Id == gameObject->GetSpellId())
4605 gameObject->SetSpellId(0);
4606 m_caster->RemoveGameObject(gameObject, true);
4607 }
4608 m_caster->m_ObjectSlot[slot].Clear();
4609 }
4610 }
4611
4612 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4613
4614 float x, y, z;
4615 // If dest location if present
4616 if (m_targets.HasDst())
4617 destTarget->GetPosition(x, y, z);
4618 // Summon in random point all other units if location present
4619 else
4621
4622 Map* map = m_caster->GetMap();
4623 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), G3D::Quat(), 0, GO_STATE_READY))
4624 {
4625 delete pGameObj;
4626 return;
4627 }
4628
4629 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4630 int32 duration = m_spellInfo->GetDuration();
4631 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4632 pGameObj->SetSpellId(m_spellInfo->Id);
4633 m_caster->AddGameObject(pGameObj);
4634
4635 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4636
4637 map->AddToMap(pGameObj, true);
4638
4639 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4640}
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT4
Definition: SharedDefines.h:885
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT1
Definition: SharedDefines.h:882
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT3
Definition: SharedDefines.h:884
@ SPELL_EFFECT_SUMMON_OBJECT_SLOT2
Definition: SharedDefines.h:883
#define DEFAULT_WORLD_OBJECT_SIZE
Definition: ObjectDefines.h:45
ObjectGuid m_ObjectSlot[MAX_GAMEOBJECT_SLOT]
Definition: Unit.h:1899

References Unit::AddGameObject(), Map::AddToMap(), ObjectGuid::Clear(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Map::GetGameObject(), Object::GetGUID(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, Unit::m_ObjectSlot, m_spellInfo, m_targets, Unit::RemoveGameObject(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_SUMMON_OBJECT_SLOT1, SPELL_EFFECT_SUMMON_OBJECT_SLOT2, SPELL_EFFECT_SUMMON_OBJECT_SLOT3, and SPELL_EFFECT_SUMMON_OBJECT_SLOT4.

◆ EffectSummonObjectWild()

void Spell::EffectSummonObjectWild ( SpellEffIndex  effIndex)
3741{
3743 return;
3744
3745 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3746
3747 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3748
3749 WorldObject* target = focusObject;
3750 if (!target)
3751 target = m_caster;
3752
3753 float x, y, z;
3754 if (m_targets.HasDst())
3755 destTarget->GetPosition(x, y, z);
3756 else
3758
3759 Map* map = target->GetMap();
3760
3761 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
3762 {
3763 delete pGameObj;
3764 return;
3765 }
3766
3767 int32 duration = m_spellInfo->GetDuration();
3768
3769 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3770 pGameObj->SetSpellId(m_spellInfo->Id);
3771
3772 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3773
3774 // Wild object not have owner and check clickable by players
3775 map->AddToMap(pGameObj, true);
3776
3777 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3778 if (Player* player = m_caster->ToPlayer())
3779 if (Battleground* bg = player->GetBattleground())
3780 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3781
3782 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3783 {
3784 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3785 linkedTrap->SetSpellId(m_spellInfo->Id);
3786 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3787 }
3788}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition: SharedDefines.h:1586
@ TEAM_ALLIANCE
Definition: SharedDefines.h:760
@ TEAM_HORDE
Definition: SharedDefines.h:761
GameObject * GetLinkedTrap()
Definition: GameObject.cpp:2735
GameobjectTypes GetGoType() const
Definition: GameObject.h:203

References Map::AddToMap(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), focusObject, GAMEOBJECT_TYPE_FLAGDROP, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), GameObject::GetGoType(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, m_caster, m_spellInfo, m_targets, GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, TEAM_ALLIANCE, TEAM_HORDE, and Object::ToPlayer().

◆ EffectSummonPet()

void Spell::EffectSummonPet ( SpellEffIndex  effIndex)
3137{
3139 return;
3140
3141 if (!m_originalCaster)
3142 return;
3143
3144 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3145 int32 duration = m_spellInfo->GetDuration();
3146
3147 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3148 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3149
3150 Player* owner = m_originalCaster->ToPlayer();
3151 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3153
3154 if (!owner)
3155 {
3156 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3157 if (properties)
3158 {
3159 // Xinef: unsummon old guardian
3160 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3161 oldPet->UnSummon();
3162 SummonGuardian(effIndex, petentry, properties, 1, false);
3163 }
3164 return;
3165 }
3166
3167 Pet* OldSummon = owner->GetPet();
3168
3169 // if pet requested type already exist
3170 if (OldSummon)
3171 {
3172 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3173 {
3174 // pet in corpse state can't be summoned
3175 if (OldSummon->isDead())
3176 return;
3177
3178 ASSERT(OldSummon->GetMap() == owner->GetMap());
3179
3180 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3181
3182 float px, py, pz;
3183 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3184
3185 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3186 OldSummon->UpdateObjectVisibility();
3187
3188 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3189 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3190 // notify player
3191 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3192 owner->SendClearCooldown(itr->first, OldSummon);
3193
3194 // actually clear cooldowns
3195 OldSummon->m_CreatureSpellCooldowns.clear();
3196 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3197 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3198 {
3199 Aura const* aura = i->second->GetBase();
3200 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3201 OldSummon->RemoveAura(i);
3202 else
3203 ++i;
3204 }
3205 return;
3206 }
3207
3208 if (owner->IsPlayer())
3209 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3210 else
3211 return;
3212 }
3213
3214 float x, y, z;
3215 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3216 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3217 if (!pet)
3218 return;
3219
3220 if (m_caster->IsCreature())
3221 {
3222 if (m_caster->ToCreature()->IsTotem())
3224 else
3226 }
3227
3229
3230 // Reset cooldowns
3232 {
3233 pet->m_CreatureSpellCooldowns.clear();
3234 owner->PetSpellInitialize();
3235 }
3236
3237 // Set health to max if new pet is summoned
3238 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3239 // pet should have full health
3240 pet->SetHealth(pet->GetMaxHealth());
3241
3242 // generate new name for summon pet
3243 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3244 if (!new_name.empty())
3245 pet->SetName(new_name);
3246
3247 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3248}
@ SPELLMOD_DURATION
Definition: SpellDefines.h:77
@ REACT_DEFENSIVE
Definition: Unit.h:549
@ REACT_AGGRESSIVE
Definition: Unit.h:550
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:251
void SetReactState(ReactStates state)
A creature can have 3 ReactStates : Agressive, Passive, Neutral.
Definition: Creature.h:94
Definition: TemporarySummon.h:95
void SetName(std::string const &newname)
Definition: Object.h:459
float GetObjectSize() const
Definition: Object.cpp:2771
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14659
bool IsPetAura(Aura const *aura)
Definition: Unit.cpp:17332
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition: Unit.cpp:19126
Powers getPowerType() const
Definition: Unit.h:1052
bool isDead() const
Definition: Unit.h:1660
bool CanBeSentToClient() const
Definition: SpellAuras.cpp:1137
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition: SpellEffects.cpp:5956

References ASSERT, Aura::CanBeSentToClient(), CLASS_CONTEXT_PET, CLASS_HUNTER, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetEntry(), Unit::GetGuardianPet(), WorldObject::GetMap(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetObjectSize(), Position::GetOrientation(), Player::GetPet(), Unit::getPowerType(), Unit::GetSpellModOwner(), SpellInfo::Id, Player::IsClass(), Object::IsCreature(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Object::IsPlayer(), Unit::IsTotem(), m_caster, Creature::m_CreatureSpellCooldowns, m_originalCaster, m_spellInfo, Unit::NearTeleportTo(), PET_SAVE_NOT_IN_SLOT, Player::PetSpellInitialize(), REACT_AGGRESSIVE, REACT_DEFENSIVE, Unit::RemoveAura(), Player::RemovePet(), Player::SendClearCooldown(), Unit::SetHealth(), WorldObject::SetName(), Unit::SetPower(), Creature::SetReactState(), Unit::SetUInt32Value(), sObjectMgr, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, sSummonPropertiesStore, SUMMON_PET, SummonGuardian(), Player::SummonPet(), Object::ToCreature(), Object::ToPlayer(), UNIT_CREATED_BY_SPELL, and Unit::UpdateObjectVisibility().

◆ EffectSummonPlayer()

void Spell::EffectSummonPlayer ( SpellEffIndex  effIndex)
4224{
4225 // workaround - this effect should not use target map
4227 return;
4228
4229 if (!unitTarget)
4230 return;
4231
4232 Player* player = unitTarget->ToPlayer();
4233 if (!player)
4234 {
4235 return;
4236 }
4237
4238 // Evil Twin (ignore player summon, but hide this for summoner)
4239 // Xinef: Unit Target may be on other map!!!, Need workaround
4240 if (unitTarget->HasAura(23445))
4241 return;
4242
4243 float x, y, z;
4244 m_caster->GetPosition(x, y, z);
4245
4246 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4247
4248 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4249 data << m_caster->GetGUID(); // summoner guid
4250 data << uint32(m_caster->GetZoneId()); // summoner zone
4251 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4252 player->GetSession()->SendPacket(&data);
4253}
#define MAX_PLAYER_SUMMON_DELAY
Definition: Player.h:929
@ SMSG_SUMMON_REQUEST
Definition: Opcodes.h:713
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition: Player.cpp:16324

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonRaFFriend()

void Spell::EffectSummonRaFFriend ( SpellEffIndex  effIndex)
6325{
6327 return;
6328
6329 if (!m_caster->IsPlayer())
6330 return;
6331
6332 if (!unitTarget)
6333 return;
6334
6335 Player* player = unitTarget->ToPlayer();
6336 if (!player)
6337 {
6338 return;
6339 }
6340
6341 float x, y, z;
6342 m_caster->GetPosition(x, y, z);
6344 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6345 data << m_caster->GetGUID();
6346 data << uint32(m_caster->GetZoneId());
6347 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6348 player->GetSession()->SendPacket(&data);
6349}

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), Player::GetSession(), WorldObject::GetZoneId(), IN_MILLISECONDS, Object::IsPlayer(), m_caster, MAX_PLAYER_SUMMON_DELAY, WorldSession::SendPacket(), Player::SetSummonPoint(), SMSG_SUMMON_REQUEST, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2330{
2332 return;
2333
2334 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2335 if (!entry)
2336 return;
2337
2338 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2339 if (!properties)
2340 {
2341 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2342 return;
2343 }
2344
2345 if (!m_originalCaster)
2346 return;
2347
2348 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2349 int32 duration = m_spellInfo->GetDuration();
2350 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
2351 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2352
2353 TempSummon* summon = nullptr;
2354
2355 // determine how many units should be summoned
2356 uint32 numSummons;
2357
2358 // some spells need to summon many units, for those spells number of summons is stored in effect value
2359 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2360 // and in spell attributes, possibly we need to add a table for those)
2361 // so here's a list of MiscValueB values, which is currently most generic check
2362 switch (properties->Id)
2363 {
2364 case 64:
2365 case 61:
2366 case 1101:
2367 case 66:
2368 case 648:
2369 case 2301:
2370 case 1061:
2371 case 1261:
2372 case 629:
2373 case 181:
2374 case 715:
2375 case 1562:
2376 case 833:
2377 case 1161:
2378 case 713: // xinef, bloodworms
2379 numSummons = (damage > 0) ? damage : 1;
2380 break;
2381 default:
2382 numSummons = 1;
2383 break;
2384 }
2385
2386 switch (properties->Category)
2387 {
2391 if (properties->Flags & 512)
2392 {
2393 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2394 break;
2395 }
2396 switch (properties->Type)
2397 {
2398 case SUMMON_TYPE_PET:
2401 case SUMMON_TYPE_MINION:
2402 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2403 break;
2404 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2407 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2408 break;
2410 case SUMMON_TYPE_TOTEM:
2411 {
2412 // protection code
2413 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2414 if (!summon || !summon->IsTotem())
2415 return;
2416
2417 // Mana Tide Totem
2418 if (m_spellInfo->Id == 16190)
2420
2421 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2422 {
2423 summon->SetMaxHealth(damage);
2424 summon->SetHealth(damage);
2425 }
2426 break;
2427 }
2428 case SUMMON_TYPE_JEEVES:
2430 {
2431 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2432 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2433 return;
2434
2435 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2437
2438 summon->SetImmuneToAll(true);
2440
2441 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2442 //summon->AI()->EnterEvadeMode();
2443 if (properties->Type != SUMMON_TYPE_JEEVES)
2444 {
2445 summon->GetMotionMaster()->Clear(false);
2447 }
2448 break;
2449 }
2450 default:
2451 {
2452 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2453
2454 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2455
2456 for (uint32 count = 0; count < numSummons; ++count)
2457 {
2458 Position pos;
2459 if (count == 0)
2460 pos = *destTarget;
2461 else
2462 // randomize position for multiple summons
2463 pos = m_caster->GetRandomPoint(*destTarget, radius);
2464
2465 summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2466 if (!summon)
2467 continue;
2468
2469 summon->SetTempSummonType(summonType);
2470
2471 if (properties->Category == SUMMON_CATEGORY_ALLY)
2472 {
2475 }
2476
2477 ExecuteLogEffectSummonObject(effIndex, summon);
2478 }
2479 return;
2480 }
2481 }//switch
2482 break;
2484 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2485 if (m_originalCaster)
2487 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2488 break;
2490 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, personalSpawn);
2491 break;
2493 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2494 // to cast a ride vehicle spell on the summoned unit.
2495 //float x, y, z;
2496 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2497 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2498 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2500
2501 summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id, 0, personalSpawn);
2502 if (!summon || !summon->IsVehicle())
2503 return;
2504
2505 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2507 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2508 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2509 {
2510 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2511 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2512 spellId = spellInfo->Id;
2513 }
2514
2515 // xinef: if we have small value, it indicates seat position
2516 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2517 m_originalCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2518 else
2519 m_originalCaster->CastSpell(summon, spellId, true);
2520
2521 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2522 //uint32 faction = properties->Faction;
2523 //if (!faction)
2524 uint32 faction = m_originalCaster->GetFaction();
2525
2526 summon->SetFaction(faction);
2527 break;
2528 }
2529
2530 if (summon)
2531 {
2533 ExecuteLogEffectSummonObject(effIndex, summon);
2534 }
2535}
#define MAX_VEHICLE_SEATS
Definition: DBCStructure.h:2023
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition: DBCEnums.h:428
@ SUMMON_TYPE_VEHICLE2
Definition: SharedDefines.h:3304
@ SUMMON_TYPE_LIGHTWELL
Definition: SharedDefines.h:3305
@ SUMMON_TYPE_MINION
Definition: SharedDefines.h:3297
@ SUMMON_TYPE_GUARDIAN
Definition: SharedDefines.h:3296
@ SUMMON_TYPE_JEEVES
Definition: SharedDefines.h:3306
@ SUMMON_TYPE_PET
Definition: SharedDefines.h:3295
@ SUMMON_TYPE_TOTEM
Definition: SharedDefines.h:3298
@ SUMMON_TYPE_VEHICLE
Definition: SharedDefines.h:3303
@ SUMMON_TYPE_MINIPET
Definition: SharedDefines.h:3299
@ SUMMON_TYPE_GUARDIAN2
Definition: SharedDefines.h:3300
@ SUMMON_CATEGORY_VEHICLE
Definition: SharedDefines.h:3287
@ SUMMON_CATEGORY_ALLY
Definition: SharedDefines.h:3284
@ SUMMON_CATEGORY_WILD
Definition: SharedDefines.h:3283
@ SUMMON_CATEGORY_UNK
Definition: SharedDefines.h:3288
@ SPELL_AURA_CONTROL_VEHICLE
Definition: SpellAuraDefines.h:299
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition: VehicleDefines.h:52
TempSummonType
Definition: Object.h:44
@ TEMPSUMMON_DEAD_DESPAWN
Definition: Object.h:51
@ REACT_PASSIVE
Definition: Unit.h:548
@ UNIT_MASK_MINION
Definition: UnitDefines.h:136
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:292
@ MOTION_SLOT_ACTIVE
Definition: MotionMaster.h:64
void SelectLevel(bool changelevel=true)
Definition: Creature.cpp:1508
uint32 npcflag
Definition: CreatureData.h:199
void SetTempSummonType(TempSummonType type)
Definition: TemporarySummon.cpp:277
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1502
void SetFaction(uint32 faction)
Definition: Unit.cpp:10056
virtual float GetFollowAngle() const
Definition: Unit.h:1711
void SetOwnerGUID(ObjectGuid owner)
Definition: Unit.cpp:10573
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:706
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:15523
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:681
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:728
void RemoveAllMinionsByEntry(uint32 entry)
Definition: Unit.cpp:10858
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition: Unit.h:874
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=nullptr, uint32 duration=0, WorldObject *summoner=nullptr, uint32 spellId=0, uint32 vehId=0, bool visibleBySummonerOnly=false)
Definition: Object.cpp:2163
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE, bool inheritWalkState=true)
The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE.
Definition: MotionMaster.cpp:409
void Clear(bool reset=true)
Definition: MotionMaster.h:167
uint32 Flags
Definition: DBCStructure.h:1914
uint32 Type
Definition: DBCStructure.h:1912
uint32 Id
Definition: DBCStructure.h:1909

References Unit::CastCustomSpell(), Unit::CastSpell(), SummonPropertiesEntry::Category, MotionMaster::Clear(), Unit::CountPctFromMaxHealth(), damage, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), SummonPropertiesEntry::Flags, Creature::GetCreatureTemplate(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Object::GetGUID(), WorldObject::GetMap(), Unit::GetMotionMaster(), Position::GetPositionZ(), WorldObject::GetRandomPoint(), Unit::GetSpellModOwner(), SpellInfo::HasAura(), Unit::HasUnitTypeMask(), SpellInfo::Id, SummonPropertiesEntry::Id, Unit::IsTotem(), Unit::IsVehicle(), LOG_ERROR, m_caster, m_originalCaster, Position::m_positionZ, m_spellInfo, MAX_VEHICLE_SEATS, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), CreatureTemplate::npcflag, PET_FOLLOW_DIST, REACT_PASSIVE, Unit::RemoveAllMinionsByEntry(), Unit::ReplaceAllNpcFlags(), Creature::SelectLevel(), Unit::SetCreatorGUID(), Unit::SetFaction(), Unit::SetHealth(), Unit::SetImmuneToAll(), Unit::SetMaxHealth(), Unit::SetOwnerGUID(), Creature::SetReactState(), TempSummon::SetTempSummonType(), SPELL_AURA_CONTROL_VEHICLE, SPELL_EFFECT_HANDLE_HIT, SPELLMOD_DURATION, SPELLVALUE_BASE_POINT0, sSpellMgr, sSummonPropertiesStore, SUMMON_CATEGORY_ALLY, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, SUMMON_CATEGORY_UNK, SUMMON_CATEGORY_VEHICLE, SUMMON_CATEGORY_WILD, SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER, SUMMON_TYPE_GUARDIAN, SUMMON_TYPE_GUARDIAN2, SUMMON_TYPE_JEEVES, SUMMON_TYPE_LIGHTWELL, SUMMON_TYPE_MINION, SUMMON_TYPE_MINIPET, SUMMON_TYPE_PET, SUMMON_TYPE_TOTEM, SUMMON_TYPE_VEHICLE, SUMMON_TYPE_VEHICLE2, Map::SummonCreature(), WorldObject::SummonCreature(), SummonGuardian(), TEMPSUMMON_DEAD_DESPAWN, TEMPSUMMON_TIMED_DESPAWN, SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3081{
3083 return;
3084
3085 if (m_caster->GetPetGUID())
3086 return;
3087
3088 if (!unitTarget)
3089 return;
3090
3091 if (!unitTarget->IsCreature())
3092 return;
3093
3094 Creature* creatureTarget = unitTarget->ToCreature();
3095
3096 if (creatureTarget->IsPet())
3097 return;
3098
3100 return;
3101
3102 // cast finish successfully
3103 //SendChannelUpdate(0);
3104 finish();
3105
3106 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3107 if (!pet) // in very specific state like near world end/etc.
3108 return;
3109
3110 // "kill" original creature
3111 creatureTarget->DespawnOrUnsummon();
3112
3113 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3114
3115 // prepare visual effect for levelup
3116 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3117
3118 // add to world
3119 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3120
3121 // visual effect for levelup
3122 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3123
3124 // caster have pet now
3125 m_caster->SetMinion(pet, true);
3126
3127 pet->InitTalentForLevel();
3128
3129 if (m_caster->IsPlayer())
3130 {
3133 }
3134}
@ UNIT_FIELD_LEVEL
Definition: UpdateFields.h:114

References Map::AddToMap(), CLASS_CONTEXT_PET, CLASS_HUNTER, Unit::CreateTamedPetFrom(), Creature::DespawnOrUnsummon(), effectHandleMode, finish(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetPetGUID(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), m_caster, m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), Unit::SetMinion(), Unit::SetUInt32Value(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToCreature(), Object::ToPlayer(), UNIT_FIELD_LEVEL, and unitTarget.

◆ EffectTaunt()

void Spell::EffectTaunt ( SpellEffIndex  effIndex)
3277{
3279 return;
3280
3281 if (!unitTarget)
3282 return;
3283
3284 // xinef: Hand of Reckoning, cast before checing canhavethreatlist. fixes damage against pets
3285 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3286 {
3287 m_caster->CastSpell(unitTarget, 67485, true);
3289 }
3290
3291 // this effect use before aura Taunt apply for prevent taunt already attacking target
3292 // for spell as marked "non effective at already attacking target"
3294 {
3296 return;
3297 }
3298
3300 {
3301 // Also use this effect to set the taunter's threat to the taunted creature's highest value
3302 float myThreat = unitTarget->GetThreatMgr().GetThreat(m_caster);
3304 if (topThreat > myThreat)
3305 unitTarget->GetThreatMgr().DoAddThreat(m_caster, topThreat - myThreat);
3306
3307 //Set aggro victim to caster
3309 unitTarget->GetThreatMgr().setCurrentVictim(forcedVictim);
3310 }
3311}
@ SPELL_AURA_MOD_TAUNT
Definition: SpellAuraDefines.h:74
Definition: ThreatMgr.h:48
float GetThreat() const
Definition: ThreatMgr.h:62
HostileReference * getMostHated() const
Definition: ThreatMgr.h:168
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition: ThreatMgr.cpp:261
bool empty() const
Definition: ThreatMgr.h:163
void setCurrentVictim(HostileReference *hostileRef)
Definition: ThreatMgr.cpp:572
void DoAddThreat(Unit *victim, float threat)
Definition: ThreatMgr.cpp:453
float GetThreat(Unit *victim, bool alsoSearchOfflineList=false)
Definition: ThreatMgr.cpp:525
ThreatContainer & GetOnlineContainer()
Definition: ThreatMgr.h:275
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition: Unit.cpp:14609

References Unit::CanHaveThreatList(), Unit::CastSpell(), Unit::CombatStart(), ThreatMgr::DoAddThreat(), effectHandleMode, ThreatContainer::empty(), ThreatContainer::getMostHated(), ThreatMgr::GetOnlineContainer(), ThreatContainer::getReferenceByTarget(), HostileReference::GetThreat(), ThreatMgr::GetThreat(), Unit::GetThreatMgr(), Unit::GetVictim(), SpellInfo::HasAura(), SpellInfo::Id, m_caster, m_spellInfo, SendCastResult(), ThreatMgr::setCurrentVictim(), SPELL_AURA_MOD_TAUNT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_FAILED_DONT_REPORT, and unitTarget.

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1181{
1183 return;
1184
1185 if (!unitTarget || unitTarget->IsInFlight())
1186 return;
1187
1188 if (unitTarget->IsPlayer())
1189 {
1190 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1191 }
1192
1193 // Pre effects
1194 switch (m_spellInfo->Id)
1195 {
1196 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1197 if (Player* target = unitTarget->ToPlayer())
1198 {
1199 uint32 mapid = destTarget->GetMapId();
1200 float x, y, z, orientation;
1201 destTarget->GetPosition(x, y, z, orientation);
1202 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1203 }
1204 return;
1205 }
1206
1207 // If not exist data for dest location - return
1208 if (!m_targets.HasDst())
1209 {
1210 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1211 return;
1212 }
1213
1214 // Init dest coordinates
1215 uint32 mapid = destTarget->GetMapId();
1216 if (mapid == MAPID_INVALID)
1217 mapid = unitTarget->GetMapId();
1218 float x, y, z, orientation;
1219 destTarget->GetPosition(x, y, z, orientation);
1220 if (!orientation && m_targets.GetUnitTarget())
1221 orientation = m_targets.GetUnitTarget()->GetOrientation();
1222 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1223
1224 if (mapid == unitTarget->GetMapId())
1225 {
1226 if (unitTarget->GetVehicleKit()) // we are vehicle!
1227 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1228 else
1229 {
1231 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1232 if (unitTarget->IsPlayer()) // pussywizard: for units it's done inside NearTeleportTo
1234 }
1235 }
1236 else if (unitTarget->IsPlayer())
1237 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1238 else
1239 {
1240 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1241 return;
1242 }
1243
1244 // post effects for TARGET_DEST_DB
1245 switch (m_spellInfo->Id)
1246 {
1247 // Dimensional Ripper - Everlook
1248 case 23442:
1249 {
1250 int32 r = irand(0, 119);
1251 if (r >= 70) // 7/12 success
1252 {
1253 if (r < 100) // 4/12 evil twin
1254 m_caster->CastSpell(m_caster, 23445, true);
1255 else // 1/12 fire
1256 m_caster->CastSpell(m_caster, 23449, true);
1257 }
1258 return;
1259 }
1260 // Ultrasafe Transporter: Toshley's Station
1261 case 36941:
1262 {
1263 if (roll_chance_i(50)) // 50% success
1264 {
1265 int32 rand_eff = urand(1, 7);
1266 switch (rand_eff)
1267 {
1268 case 1:
1269 // soul split - evil
1270 m_caster->CastSpell(m_caster, 36900, true);
1271 break;
1272 case 2:
1273 // soul split - good
1274 m_caster->CastSpell(m_caster, 36901, true);
1275 break;
1276 case 3:
1277 // Increase the size
1278 m_caster->CastSpell(m_caster, 36895, true);
1279 break;
1280 case 4:
1281 // Decrease the size
1282 m_caster->CastSpell(m_caster, 36893, true);
1283 break;
1284 case 5:
1285 // Transform
1286 {
1288 m_caster->CastSpell(m_caster, 36897, true);
1289 else
1290 m_caster->CastSpell(m_caster, 36899, true);
1291 break;
1292 }
1293 case 6:
1294 // chicken
1295 m_caster->CastSpell(m_caster, 36940, true);
1296 break;
1297 case 7:
1298 // evil twin
1299 m_caster->CastSpell(m_caster, 23445, true);
1300 break;
1301 }
1302 }
1303 return;
1304 }
1305 }
1306}
@ TELE_TO_SPELL
Definition: Player.h:825
@ TELE_TO_GM_MODE
Definition: Player.h:821
#define MAPID_INVALID
Definition: Position.h:247
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2091
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1331
Vehicle * GetVehicleKit() const
Definition: Unit.h:1739
void TeleportVehicle(float x, float y, float z, float ang)
Definition: Vehicle.cpp:562

References Unit::CastSpell(), destTarget, effectHandleMode, Position::GetExactDist(), WorldObject::GetMap(), WorldLocation::GetMapId(), Position::GetOrientation(), Position::GetPosition(), Player::GetTeamId(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleKit(), SpellCastTargets::HasDst(), SpellInfo::Id, irand(), Map::IsDungeon(), Unit::IsInFlight(), Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_spellInfo, m_targets, MAPID_INVALID, Unit::NearTeleportTo(), roll_chance_i(), SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, sScriptMgr, TEAM_ALLIANCE, TELE_TO_GM_MODE, TELE_TO_SPELL, Player::TeleportTo(), Vehicle::TeleportVehicle(), Object::ToPlayer(), unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3666{
3668 return;
3669
3670 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3671 return;
3672
3673 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3675 return;
3676
3678}
void AddThreat(Unit *victim, float fThreat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell=nullptr)
Definition: Unit.cpp:14648

References Unit::AddThreat(), Unit::CanHaveThreatList(), damage, effectHandleMode, Unit::IsAlive(), Unit::IsFriendlyTo(), m_caster, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5890{
5892 return;
5893
5894 if (m_caster->IsPlayer())
5895 {
5896 if (Aura* aur = m_caster->GetAura(49152))
5897 aur->RecalculateAmountOfEffects();
5898 else
5899 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5900
5902 }
5903}
void SetCanTitanGrip(bool value)
Definition: Player.cpp:13153

References Unit::CastSpell(), effectHandleMode, Unit::GetAura(), Object::IsPlayer(), m_caster, Player::SetCanTitanGrip(), SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), and unitTarget.

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2818{
2820 return;
2821
2822 if (!m_caster->IsPlayer())
2823 return;
2824 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
2825 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
2826 // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
2827}

References effectHandleMode, Object::IsPlayer(), m_caster, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5364{
5366 return;
5367
5368 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5369
5370 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5371
5372 if (!goinfo)
5373 {
5374 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5375 return;
5376 }
5377
5378 float fx, fy, fz;
5379
5380 if (m_targets.HasDst())
5381 destTarget->GetPosition(fx, fy, fz);
5382 //FIXME: this can be better check for most objects but still hack
5383 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5384 {
5385 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5387 }
5388 else
5389 {
5390 //GO is always friendly to it's creator, get range for friends
5391 float min_dis = m_spellInfo->GetMinRange(true);
5392 float max_dis = m_spellInfo->GetMaxRange(true);
5393 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5394
5396 }
5397
5398 // Seaforium charge
5399 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5400 {
5401 fx = m_caster->GetPositionX();
5402 fy = m_caster->GetPositionY();
5403 fz = m_caster->GetPositionZ();
5404 }
5405
5406 Map* cMap = m_caster->GetMap();
5407
5408 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5409
5410 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), G3D::Quat(), 100, GO_STATE_READY))
5411 {
5412 delete pGameObj;
5413 return;
5414 }
5415
5416 int32 duration = m_spellInfo->GetDuration();
5417
5418 switch (goinfo->type)
5419 {
5421 {
5423 m_caster->AddGameObject(pGameObj); // will removed at spell cancel
5424
5425 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5426 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5427 int32 lastSec = 0;
5428 switch (urand(0, 2))
5429 {
5430 case 0:
5431 lastSec = 3;
5432 break;
5433 case 1:
5434 lastSec = 7;
5435 break;
5436 case 2:
5437 lastSec = 13;
5438 break;
5439 }
5440
5441 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5442 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5443
5444 break;
5445 }
5447 {
5448 if (m_caster->IsPlayer())
5449 {
5450 pGameObj->AddUniqueUse(m_caster->ToPlayer());
5451 m_caster->AddGameObject(pGameObj); // will be removed at spell cancel
5452 }
5453 break;
5454 }
5455 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5456 m_caster->AddGameObject(pGameObj);
5457 break;
5460 default:
5461 break;
5462 }
5463
5464 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5465
5466 pGameObj->SetOwnerGUID(m_caster->GetGUID());
5467
5468 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
5469 pGameObj->SetSpellId(m_spellInfo->Id);
5470
5471 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5472
5473 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5474 //m_caster->AddGameObject(pGameObj);
5475 //m_ObjToDel.push_back(pGameObj);
5476
5477 cMap->AddToMap(pGameObj, true);
5478
5479 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5480 {
5481 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5482 linkedTrap->SetSpellId(m_spellInfo->Id);
5483 linkedTrap->SetOwnerGUID(m_caster->GetGUID());
5484
5485 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5486 }
5487
5488 if (Player* player = m_caster->ToPlayer())
5489 {
5490 player->SetCanTeleport(true);
5491 }
5492}
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition: SharedDefines.h:1576
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition: SharedDefines.h:1578
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1563
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1585
@ GAMEOBJECT_TYPE_FISHINGNODE
Definition: SharedDefines.h:1577
#define FISHING_BOBBER_READY_TIME
Definition: GameObject.h:117
@ UNIT_FIELD_CHANNEL_OBJECT
Definition: UpdateFields.h:93
void SetOwnerGUID(ObjectGuid owner)
Definition: GameObject.h:163
void AddUniqueUse(Player *player)
Definition: GameObject.cpp:927
float GetMinRange(bool positive=false) const
Definition: SpellInfo.cpp:2314

References Unit::AddGameObject(), Map::AddToMap(), GameObject::AddUniqueUse(), GameObject::Create(), DEFAULT_WORLD_OBJECT_SIZE, destTarget, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectSummonObject(), FISHING_BOBBER_READY_TIME, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DUEL_ARBITER, GAMEOBJECT_TYPE_FISHINGHOLE, GAMEOBJECT_TYPE_FISHINGNODE, GAMEOBJECT_TYPE_SUMMONING_RITUAL, Map::GenerateLowGuid(), WorldObject::GetClosePoint(), SpellInfo::GetDuration(), Object::GetGUID(), GameObject::GetLinkedTrap(), WorldObject::GetMap(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, m_caster, m_originalCaster, m_spellInfo, m_targets, rand_norm(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
943{
946 return;
947
948 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
949
950 // normal case
951 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
952 if (!spellInfo)
953 {
954 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
955 return;
956 }
957
958 SpellCastTargets targets;
960 {
961 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
962 return;
963 targets.SetUnitTarget(unitTarget);
964 }
965 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
966 {
967 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
968 return;
969
971 targets.SetDst(m_targets);
972
973 targets.SetUnitTarget(m_caster);
974 }
975
976 CustomSpellValues values;
977 // set basepoints for trigger with value effect
979 {
980 // maybe need to set value only when basepoints == 0?
984 }
985
986 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
987 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
988 {
989 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
990 }
991
992 // original caster guid only for GO cast
993 m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID);
994}
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition: SharedDefines.h:926
@ TARGET_FLAG_DEST_LOCATION
Definition: SpellInfo.h:52
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition: SpellInfo.cpp:1038
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:349

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_EFFECT_HANDLE_HIT, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1051{
1053 return;
1054
1055 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1056 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1057
1058 if (!spellInfo)
1059 {
1060 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1061 return;
1062 }
1063
1064 finish();
1065
1066 m_caster->CastSpell((Unit*)nullptr, spellInfo, true);
1067}

References Unit::CastSpell(), effectHandleMode, SpellInfo::Effects, finish(), SpellInfo::Id, LOG_ERROR, m_caster, m_spellInfo, SPELL_EFFECT_HANDLE_HIT, and sSpellMgr.

◆ EffectTriggerSpell()

void Spell::EffectTriggerSpell ( SpellEffIndex  effIndex)
Todo:
: move those to spell scripts
786{
789 return;
790
791 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
792
794 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
796 {
797 // special cases
798 switch (triggered_spell_id)
799 {
800 // Mirror Image
801 case 58832:
802 {
803 // Glyph of Mirror Image
804 if (m_caster->HasAura(63093))
805 m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
806
807 break;
808 }
809 // Demonic Empowerment -- succubus
810 case 54437:
811 {
815
816 // Cast Lesser Invisibility
817 unitTarget->CastSpell(unitTarget, 7870, true);
818 return;
819 }
820 // just skip
821 case 23770: // Sayge's Dark Fortune of *
822 // not exist, common cooldown can be implemented in scripts if need.
823 return;
824 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
825 case 29284:
826 {
827 // Brittle Armor
828 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
829 if (!spell)
830 return;
831
832 for (uint32 j = 0; j < spell->StackAmount; ++j)
833 m_caster->CastSpell(unitTarget, spell->Id, true);
834 return;
835 }
836 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
837 case 29286:
838 {
839 // Mercurial Shield
840 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
841 if (!spell)
842 return;
843
844 for (uint32 j = 0; j < spell->StackAmount; ++j)
845 m_caster->CastSpell(unitTarget, spell->Id, true);
846 return;
847 }
848 // Cloak of Shadows
849 case 35729:
850 {
853 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
854 {
855 // remove all harmful spells on you...
856 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
857
858 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
859 if (spell->GetAllEffectsMechanicMask() & 1 << MECHANIC_BLEED)
860 return;
861
862 bool dmgClassNone = false;
864 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
865 {
866 if ((iter->second->GetEffectMask() & (1 << i)) &&
867 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
868 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
869 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
870 {
871 dmgClassNone = false;
872 break;
873 }
874 dmgClassNone = true;
875 }
876
877 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
878 // ignore positive and passive auras
879 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
880 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
882 {
883 m_caster->RemoveAura(iter);
884 }
885 else
886 ++iter;
887 }
888 return;
889 }
890 }
891 }
892
893 // normal case
894 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
895 if (!spellInfo)
896 {
897 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
898 return;
899 }
900
901 SpellCastTargets targets;
903 {
904 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
905 return;
906 targets.SetUnitTarget(unitTarget);
907 }
908 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
909 {
910 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
911 return;
912
914 targets.SetDst(m_targets);
915
916 if (Unit* target = m_targets.GetUnitTarget())
917 targets.SetUnitTarget(target);
918 else
919 targets.SetUnitTarget(m_caster);
920 }
921
922 CustomSpellValues values;
923 // set basepoints for trigger with value effect
925 {
926 // maybe need to set value only when basepoints == 0?
930 }
931
932 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
933 if (m_caster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
934 {
935 m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
936 }
937
938 // original caster guid only for GO cast
940}
@ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
Definition: SharedDefines.h:920
@ SPELL_EFFECT_TRIGGER_SPELL
Definition: SharedDefines.h:842
@ MECHANIC_BLEED
Definition: SharedDefines.h:1340
@ DISPEL_ALL
Definition: SharedDefines.h:1379
@ SPELL_AURA_MOD_STALKED
Definition: SpellAuraDefines.h:131
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:86

References CustomSpellValues::AddSpellMod(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, MECHANIC_BLEED, SpellInfo::NeedsToBeTriggeredByCaster(), Unit::RemoveAura(), Unit::RemoveAurasByType(), Unit::RemoveMovementImpairingAuras(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), SPELL_ATTR0_NO_IMMUNITIES, SPELL_AURA_DUMMY, SPELL_AURA_MOD_STALKED, SPELL_AURA_MOD_STUN, SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_TRIGGER_SPELL, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_NONE, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_TRIGGER_SPELL, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELLFAMILY_GENERIC, SpellInfo::SpellFamilyName, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, sSpellMgr, SpellInfo::StackAmount, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_UNIT_MASK, Object::ToPlayer(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1331{
1333 return;
1334
1335 if (!unitTarget)
1336 return;
1337
1338 Player* player = unitTarget->ToPlayer();
1339 if (!player)
1340 {
1341 return;
1342 }
1343
1344 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1345
1346 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1347 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1348 player->GetGUID().ToString(), spellToUnlearn, m_caster->GetGUID().ToString());
1349}
#define SPEC_MASK_ALL
Definition: Player.h:177
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition: Player.cpp:3320

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2742{
2744 return;
2745
2746 if (!unitTarget || m_caster->IsPlayer())
2747 return;
2748
2749 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2751}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition: Player.cpp:8888

References effectHandleMode, Object::GetGUID(), Object::IsPlayer(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), and unitTarget.

◆ EffectUnused()

void Spell::EffectUnused ( SpellEffIndex  effIndex)
244{
245 // NOT USED BY ANY SPELL OR USELESS OR IMPLEMENTED IN DIFFERENT WAY IN TRINITY
246}

◆ EffectWeaponDmg()

void Spell::EffectWeaponDmg ( SpellEffIndex  effIndex)
3314{
3316 return;
3317
3318 if (!unitTarget || !unitTarget->IsAlive())
3319 return;
3320
3321 // multiple weapon dmg effect workaround
3322 // execute only the last weapon damage
3323 // and handle all effects at once
3324 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3325 {
3326 switch (m_spellInfo->Effects[j].Effect)
3327 {
3332 return; // we must calculate only at last weapon effect
3333 break;
3334 }
3335 }
3336
3337 // some spell specific modifiers
3338 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3339 int32 spell_bonus = 0; // bonus specific for spell
3340 bool normalized = false;
3341
3343 {
3345 {
3346 switch (m_spellInfo->Id)
3347 {
3348 // Trial of the Champion, Black Knight, Obliterate
3349 case 67725:
3350 case 67883:
3351 {
3352 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), 1) * 30.0f);
3353 break;
3354 }
3355 }
3356 break;
3357 }
3359 {
3360 // Devastate (player ones)
3361 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3362 {
3363 m_caster->CastSpell(unitTarget, 58567, true);
3364
3365 if (Aura* aur = unitTarget->GetAura(58567))
3366 {
3367 // 58388 - Glyph of Devastate dummy aura.
3368 if (m_caster->HasAura(58388))
3369 aur->ModStackAmount(1);
3370
3371 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3372 }
3373 }
3374 break;
3375 }
3376 case SPELLFAMILY_ROGUE:
3377 {
3378 // Fan of Knives, Hemorrhage, Ghostly Strike
3379 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3380 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3381 {
3382 // Hemorrhage
3383 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3384 {
3386 }
3387 // 50% more damage with daggers
3388 if (m_caster->IsPlayer())
3389 if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3390 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3391 AddPct(totalDamagePercentMod, 50.0f);
3392 }
3393 // Mutilate (for each hand)
3394 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3395 {
3396 bool found = false;
3397 // fast check
3399 found = true;
3400 // full aura scan
3401 else
3402 {
3404 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3405 {
3406 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3407 {
3408 found = true;
3409 break;
3410 }
3411 }
3412 }
3413
3414 if (found)
3415 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3416 }
3417 break;
3418 }
3420 {
3421 switch (m_spellInfo->Id)
3422 {
3423 case 20467: // Seal of Command Unleashed
3424 spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3426 break;
3427 case 42463: // Seals of the Pure for Seal of Vengeance/Corruption
3428 case 53739:
3430 AddPct(totalDamagePercentMod, sealsOfPure->GetAmount());
3431 break;
3432 case 53385: // Divine Storm deals normalized damage
3433 normalized = true;
3434 break;
3435 default:
3436 break;
3437 }
3438 break;
3439 }
3440 case SPELLFAMILY_SHAMAN:
3441 {
3442 // Skyshatter Harness item set bonus
3443 // Stormstrike
3444 if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634))
3445 m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff);
3446 // Lava lash damage increased by Flametongue weapon
3448 AddPct(totalDamagePercentMod, 25.0f);
3449 break;
3450 }
3451 case SPELLFAMILY_DRUID:
3452 {
3453 // Mangle (Cat): CP
3454 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3455 {
3457 }
3458 // Shred, Maul - Rend and Tear
3460 {
3461 if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3462 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3463 }
3464 break;
3465 }
3466 case SPELLFAMILY_HUNTER:
3467 {
3468 // Kill Shot
3469 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3470 {
3471 spell_bonus += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3472 }
3473 break;
3474 }
3476 {
3477 // Plague Strike
3478 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3479 {
3480 // Glyph of Plague Strike
3481 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
3482 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3483 break;
3484 }
3485 // Blood Strike
3486 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3487 {
3488 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3489 //Death Knight T8 Melee 4P Bonus
3490 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3491 AddPct(disease_amt, aurEff->GetAmount());
3492
3493 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
3494
3495 // Glyph of Blood Strike
3496 if (m_caster->GetAuraEffect(59332, EFFECT_0))
3498 AddPct(totalDamagePercentMod, 20.0f);
3499 break;
3500 }
3501 // Death Strike
3502 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3503 {
3504 // Glyph of Death Strike
3505 if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
3506 if (uint32 runic = std::min<uint32>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3507 AddPct(totalDamagePercentMod, runic);
3508 break;
3509 }
3510 // Obliterate (12.5% more damage per disease)
3511 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3512 {
3513 bool consumeDiseases = true;
3514 // Annihilation
3516 // Do not consume diseases if roll sucesses
3517 if (roll_chance_i(aurEff->GetAmount()))
3518 consumeDiseases = false;
3519
3520 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3521 //Death Knight T8 Melee 4P Bonus
3522 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3523 AddPct(disease_amt, aurEff->GetAmount());
3524
3525 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
3526 break;
3527 }
3528 // Blood-Caked Strike - Blood-Caked Blade
3529 if (m_spellInfo->SpellIconID == 1736)
3530 {
3531 int32 weaponDamage = m_caster->CalculateDamage(m_attackType, false, true);
3532 ApplyPct(weaponDamage, std::min(uint32(3), unitTarget->GetDiseasesByCaster(m_caster->GetGUID())) * 12.5f);
3533 spell_bonus = weaponDamage;
3534 break;
3535 }
3536 // Heart Strike
3537 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3538 {
3539 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3540 //Death Knight T8 Melee 4P Bonus
3541 if (AuraEffect* aurEff = m_caster->GetAuraEffectDummy(64736))
3542 AddPct(disease_amt, aurEff->GetAmount());
3543
3544 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
3545 break;
3546 }
3547 // Rune Strike
3548 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3549 {
3550 spell_bonus += int32(0.15f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
3551 }
3552
3553 break;
3554 }
3555 }
3556
3557 float weaponDamagePercentMod = 100.0f;
3558 int32 fixed_bonus = 0;
3559
3560 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3561 {
3562 switch (m_spellInfo->Effects[j].Effect)
3563 {
3566 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3567 break;
3569 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3570 normalized = true;
3571 break;
3573 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3574 break;
3575 default:
3576 break; // not weapon damage effect, just skip
3577 }
3578 }
3579
3580 // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
3581 if (fixed_bonus || spell_bonus)
3582 {
3583 UnitMods unitMod;
3584 switch (m_attackType)
3585 {
3586 default:
3587 case BASE_ATTACK:
3588 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3589 break;
3590 case OFF_ATTACK:
3591 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3592 break;
3593 case RANGED_ATTACK:
3594 unitMod = UNIT_MOD_DAMAGE_RANGED;
3595 break;
3596 }
3597
3599 {
3600 float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
3601 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3602 spell_bonus = int32(spell_bonus * weapon_total_pct);
3603 }
3604 }
3605
3606 int32 weaponDamage = 0;
3607 // Dancing Rune Weapon
3608 if (m_caster->GetEntry() == 27893)
3609 {
3610 if (Unit* owner = m_caster->GetOwner())
3611 weaponDamage = owner->CalculateDamage(m_attackType, normalized, true);
3612 }
3613 else if (m_spellInfo->Id == 5019) // Wands
3614 {
3615 weaponDamage = m_caster->CalculateDamage(m_attackType, true, false);
3616 }
3617 else
3618 {
3619 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
3620 }
3621
3622 // Sequence is important
3623 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3624 {
3625 // We assume that a spell have at most one fixed_bonus
3626 // and at most one weaponDamagePercentMod
3627 switch (m_spellInfo->Effects[j].Effect)
3628 {
3632 weaponDamage += fixed_bonus;
3633 break;
3635 ApplyPct(weaponDamage, weaponDamagePercentMod);
3636 default:
3637 break; // not weapon damage effect, just skip
3638 }
3639 }
3640
3641 weaponDamage += spell_bonus;
3642 ApplyPct(weaponDamage, totalDamagePercentMod);
3643
3644 // prevent negative damage
3645 uint32 eff_damage(std::max(weaponDamage, 0));
3646
3647 // Add melee damage bonuses (also check for negative)
3650
3651 // Meteor like spells (divided damage to targets)
3653 {
3654 uint32 count = 0;
3655 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3656 if (ihit->effectMask & (1 << effIndex))
3657 ++count;
3658
3659 eff_damage /= count; // divide to all targets
3660 }
3661
3662 m_damage += eff_damage;
3663}
@ POWER_RUNIC_POWER
Definition: SharedDefines.h:275
@ SPELL_EFFECT_NORMALIZED_WEAPON_DMG
Definition: SharedDefines.h:899
@ SPELL_EFFECT_WEAPON_PERCENT_DAMAGE
Definition: SharedDefines.h:809
@ AURA_STATE_DEADLY_POISON
Definition: SharedDefines.h:1308
@ AURA_STATE_BLEEDING
Definition: SharedDefines.h:1310
@ DISPEL_POISON
Definition: SharedDefines.h:1376
@ SPELL_AURA_ADD_PCT_MODIFIER
Definition: SpellAuraDefines.h:171
@ ITEM_SUBCLASS_WEAPON_DAGGER
Definition: ItemTemplate.h:359
UnitMods
Definition: Unit.h:142
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:166
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:167
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:165
@ TOTAL_PCT
Definition: Unit.h:129
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13271
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition: Unit.cpp:5821
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition: Unit.cpp:5550
float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const
Definition: Unit.cpp:15283
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition: Unit.cpp:2984
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition: Unit.cpp:11932
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition: Unit.cpp:13069

References AddComboPointGain(), AddPct(), ApplyPct(), AURA_STATE_BLEEDING, AURA_STATE_DEADLY_POISON, BASE_ATTACK, Unit::CalculateDamage(), CalculateSpellDamage(), Unit::CastSpell(), DISPEL_POISON, EFFECT_0, EFFECT_1, EFFECT_2, effectHandleMode, SpellInfo::Effects, Unit::GetAppliedAuras(), Unit::GetAura(), Unit::GetAuraEffect(), Unit::GetAuraEffectDummy(), Unit::GetDiseasesByCaster(), Unit::GetDummyAuraEffect(), Object::GetEntry(), Object::GetGUID(), Unit::GetModifierValue(), Unit::GetOwner(), Unit::GetPower(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), Player::GetWeaponForAttack(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), Unit::HasAuraType(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), Unit::IsScriptOverriden(), ITEM_SUBCLASS_WEAPON_DAGGER, m_attackType, m_caster, m_damage, m_spellInfo, m_spellSchoolMask, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::MeleeDamageBonusDone(), Unit::MeleeDamageBonusTaken(), OFF_ATTACK, POWER_RUNIC_POWER, RANGED_ATTACK, roll_chance_i(), SPELL_ATTR0_CU_SHARE_DAMAGE, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_DUMMY, SPELL_AURA_MOD_DECREASE_SPEED, SPELL_EFFECT_HANDLE_LAUNCH_TARGET, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, Unit::SpellBaseDamageBonusDone(), SPELLFAMILY_DEATHKNIGHT, SPELLFAMILY_DRUID, SPELLFAMILY_GENERIC, SPELLFAMILY_HUNTER, SPELLFAMILY_PALADIN, SPELLFAMILY_ROGUE, SPELLFAMILY_SHAMAN, SPELLFAMILY_WARRIOR, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, SpellInfo::SpellIconID, Object::ToPlayer(), TOTAL_PCT, UNIT_MOD_DAMAGE_MAINHAND, UNIT_MOD_DAMAGE_OFFHAND, UNIT_MOD_DAMAGE_RANGED, and unitTarget.

◆ ExecuteLogEffectCreateItem()

void Spell::ExecuteLogEffectCreateItem ( uint8  effIndex,
uint32  entry 
)
5146{
5147 InitEffectExecuteData(effIndex);
5148 *m_effectExecuteData[effIndex] << uint32(entry);
5149}
void InitEffectExecuteData(uint8 effIndex)
Definition: Spell.cpp:8474

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5152{
5153 InitEffectExecuteData(effIndex);
5154 *m_effectExecuteData[effIndex] << uint32(entry);
5155}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5132{
5133 InitEffectExecuteData(effIndex);
5134 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5135 *m_effectExecuteData[effIndex] << int32(itemId);
5136 *m_effectExecuteData[effIndex] << int32(slot);
5137}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5118{
5119 InitEffectExecuteData(effIndex);
5120 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5121 *m_effectExecuteData[effIndex] << uint32(attCount);
5122}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5125{
5126 InitEffectExecuteData(effIndex);
5127 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5128 *m_effectExecuteData[effIndex] << uint32(spellId);
5129}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5140{
5141 InitEffectExecuteData(effIndex);
5142 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5143}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5170{
5171 InitEffectExecuteData(effIndex);
5172 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5173}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ ExecuteLogEffectSummonObject()

◆ ExecuteLogEffectTakeTargetPower()

void Spell::ExecuteLogEffectTakeTargetPower ( uint8  effIndex,
Unit target,
uint32  PowerType,
uint32  powerTaken,
float  gainMultiplier 
)
5109{
5110 InitEffectExecuteData(effIndex);
5111 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5112 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5113 *m_effectExecuteData[effIndex] << uint32(PowerType);
5114 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5115}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectPowerBurn(), EffectPowerDrain(), and spell_mage_burnout_trigger::HandleDummy().

◆ ExecuteLogEffectUnsummonObject()

void Spell::ExecuteLogEffectUnsummonObject ( uint8  effIndex,
WorldObject obj 
)
5164{
5165 InitEffectExecuteData(effIndex);
5166 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5167}

References Object::GetPackGUID(), InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4484{
4485 if (!m_caster)
4486 return;
4487
4489 return;
4491
4492 if (m_spellInfo->IsChanneled())
4494
4497
4498 // Unsummon summon as possessed creatures on spell cancel
4500 {
4501 if (Unit* charm = m_caster->GetCharm())
4502 if (charm->IsCreature()
4503 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4504 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4505 ((Puppet*)charm)->UnSummon();
4506 }
4507
4508 if (Creature* creatureCaster = m_caster->ToCreature())
4509 creatureCaster->ReleaseFocus(this);
4510
4511 if (ok)
4512 {
4515 }
4516 else
4517 {
4518 if (m_caster->IsPlayer())
4519 {
4520 // Xinef: Restore spell mods in case of fail cast
4522
4523 // Xinef: Reset cooldown event in case of fail cast
4526 }
4527 return;
4528 }
4529
4530 // pussywizard:
4533
4535 {
4536 // Unsummon statue
4538 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4539 if (spellInfo && spellInfo->SpellIconID == 2056)
4540 {
4541 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4542 m_caster->setDeathState(DeathState::JustDied);
4543 return;
4544 }
4545 }
4546
4547 // potions disabled by client, send event "not in combat" if need
4550
4551 // Take mods after trigger spell (needed for 14177 to affect 48664)
4552 // mods are taken only on succesfull cast and independantly from targets of the spell
4553 if (Player* player = m_caster->GetSpellModOwner())
4554 player->RemoveSpellMods(this);
4555
4556 // xinef: clear reactive auras states after spell cast
4559
4560 // Stop Attack for some spells
4563}
@ AURA_STATE_DEFENSE
Definition: SharedDefines.h:1292
@ AURA_STATE_HUNTER_PARRY
Definition: SharedDefines.h:1298
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition: Map.h:307
@ SPELL_ATTR0_CU_ENCOUNTER_REWARD
Definition: SpellInfo.h:207
@ UNIT_MASK_PUPPET
Definition: UnitDefines.h:141
Definition: TemporarySummon.h:114
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition: PlayerUpdates.cpp:1500
virtual void setDeathState(DeathState s, bool despawn=false)
Definition: Unit.cpp:14548
void UpdateInterruptMask()
Definition: Unit.cpp:754
void ModifyAuraState(AuraStateType flag, bool apply)
Definition: Unit.cpp:10497
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit *source)
Definition: Map.cpp:3474

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), Unit::GetSpellModOwner(), Object::GetUInt32Value(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsCooldownStartedOnEvent(), Object::IsCreature(), Unit::IsNonMeleeSpellCast(), Object::IsPlayer(), Unit::IsSummon(), LOG_DEBUG, m_caster, m_spellInfo, m_spellState, m_triggeredByAuraSpell, Unit::ModifyAuraState(), Player::RemoveSpellCooldown(), Player::RestoreSpellMods(), Player::SendCooldownEvent(), Unit::setDeathState(), SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT, SPELL_ATTR0_CU_ENCOUNTER_REWARD, SPELL_STATE_FINISHED, SpellInfo::SpellIconID, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), ObjectGuid::ToString(), UNIT_CREATED_BY_SPELL, UNIT_MASK_PUPPET, UNIT_STATE_CASTING, Map::UpdateEncounterState(), Unit::UpdateInterruptMask(), and Player::UpdatePotionCooldown().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), EffectInstaKill(), EffectTameCreature(), EffectTriggerRitualOfSummoning(), SpellScript::FinishCast(), Unit::FinishSpell(), handle_delayed(), handle_immediate(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and update().

◆ FinishTargetProcessing()

void Spell::FinishTargetProcessing ( )
protected
8470{
8472}
void SendLogExecute()
Definition: Spell.cpp:5074

References SendLogExecute().

Referenced by handle_delayed(), handle_immediate(), and HandleLaunchPhase().

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

int32 Spell::GetCastTime ( ) const
inline
549{ return m_casttime; }

References m_casttime.

Referenced by Unit::InterruptSpell(), and Unit::SetCurrentCastedSpell().

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
8933{
8934 std::stringstream sstr;
8935 sstr << std::boolalpha
8936 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
8937 << " State: " << getState();
8938 return sstr.str();
8939}

References GetSpellInfo(), getState(), SpellInfo::Id, m_originalCasterGUID, and ObjectGuid::ToString().

◆ GetDelayMoment()

uint64 Spell::GetDelayMoment ( ) const
inline

◆ GetDelayStart()

uint64 Spell::GetDelayStart ( ) const
inline
564{ return m_delayStart; }

References m_delayStart.

Referenced by SpellEvent::Execute(), and RecalculateDelayMomentForDst().

◆ GetDelayTrajectory()

uint64 Spell::GetDelayTrajectory ( ) const
inline
567{ return m_delayTrajectory; }

References m_delayTrajectory.

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
578{ return m_powerCost; }

References m_powerCost.

Referenced by Unit::HandleDummyAuraProc().

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList condList 
)
2110{
2111 // this function selects which containers need to be searched for spell target
2113
2114 // filter searchers based on searched object type
2115 switch (objType)
2116 {
2123 break;
2127 break;
2128 default:
2129 break;
2130 }
2132 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2136 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2137
2138 if (condList)
2139 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2140 return retMask;
2141}
@ SPELL_ATTR2_ALLOW_DEAD_TARGET
Definition: SharedDefines.h:456
@ SPELL_ATTR3_ONLY_ON_GHOSTS
Definition: SharedDefines.h:505
@ SPELL_ATTR3_ONLY_ON_PLAYER
Definition: SharedDefines.h:501
@ GRID_MAP_TYPE_MASK_PLAYER
Definition: GridDefines.h:72
@ GRID_MAP_TYPE_MASK_CREATURE
Definition: GridDefines.h:69
@ GRID_MAP_TYPE_MASK_ALL
Definition: GridDefines.h:73
@ GRID_MAP_TYPE_MASK_GAMEOBJECT
Definition: GridDefines.h:71
@ GRID_MAP_TYPE_MASK_CORPSE
Definition: GridDefines.h:68
@ TARGET_OBJECT_TYPE_CORPSE
Definition: SpellInfo.h:106
@ TARGET_OBJECT_TYPE_GOBJ
Definition: SpellInfo.h:103
@ TARGET_OBJECT_TYPE_CORPSE_ALLY
Definition: SpellInfo.h:109
@ TARGET_OBJECT_TYPE_CORPSE_ENEMY
Definition: SpellInfo.h:108
@ TARGET_OBJECT_TYPE_GOBJ_ITEM
Definition: SpellInfo.h:104

References GRID_MAP_TYPE_MASK_ALL, GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, SpellInfo::HasAttribute(), m_spellInfo, sConditionMgr, SPELL_ATTR2_ALLOW_DEAD_TARGET, SPELL_ATTR3_ONLY_ON_GHOSTS, SPELL_ATTR3_ONLY_ON_PLAYER, TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE_ALLY, TARGET_OBJECT_TYPE_CORPSE_ENEMY, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_UNIT, and TARGET_OBJECT_TYPE_UNIT_AND_DEST.

Referenced by SearchAreaTargets(), SearchNearbyTarget(), and SelectImplicitConeTargets().

◆ GetSpellInfo()

◆ GetSpellSchoolMask()

SpellSchoolMask Spell::GetSpellSchoolMask ( ) const
inline

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
585{ return m_spellValue; }

References m_spellValue.

Referenced by DoAllEffectOnTarget().

◆ getState()

◆ GetTriggeredByAuraTickNumber()

uint32 Spell::GetTriggeredByAuraTickNumber ( ) const
inline

◆ GetTriggeredCastFlags()

TriggerCastFlags Spell::GetTriggeredCastFlags ( ) const
inline
593{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4177{
4178 if (!UpdatePointers())
4179 {
4180 // finish the spell if UpdatePointers() returned false, something wrong happened there
4181 finish(false);
4182 return 0;
4183 }
4184
4185 Player* modOwner = m_caster->GetSpellModOwner();
4186 if (modOwner)
4187 modOwner->SetSpellModTakingSpell(this, true);
4188
4189 uint64 next_time = m_delayTrajectory;
4190
4192
4193 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4194 {
4196 m_immediateHandled = true;
4198 next_time = 0;
4199 }
4200
4201 bool single_missile = (m_targets.HasDst());
4202
4203 // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
4204 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4205 {
4206 if (ihit->processed == false)
4207 {
4208 if (single_missile || ihit->timeDelay <= t_offset)
4209 {
4210 ihit->timeDelay = t_offset;
4211 DoAllEffectOnTarget(&(*ihit));
4212 }
4213 else if (next_time == 0 || ihit->timeDelay < next_time)
4214 next_time = ihit->timeDelay;
4215 }
4216 }
4217
4218 // now recheck gameobject targeting correctness
4219 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4220 {
4221 if (ighit->processed == false)
4222 {
4223 if (single_missile || ighit->timeDelay <= t_offset)
4224 DoAllEffectOnTarget(&(*ighit));
4225 else if (next_time == 0 || ighit->timeDelay < next_time)
4226 next_time = ighit->timeDelay;
4227 }
4228 }
4229
4231
4232 if (modOwner)
4233 modOwner->SetSpellModTakingSpell(this, false);
4234
4235 // All targets passed - need finish phase
4236 if (next_time == 0)
4237 {
4238 // spell is finished, perform some last features of the spell here
4240
4241 finish(true); // successfully finish spell cast
4242
4243 // return zero, spell is finished now
4244 return 0;
4245 }
4246 else
4247 {
4248 // spell is unfinished, return next execution time
4249 return next_time;
4250 }
4251}
void _handle_finish_phase()
Definition: Spell.cpp:4281
void PrepareTargetProcessing()
Definition: Spell.cpp:8464
void _handle_immediate_phase()
Definition: Spell.cpp:4253
void FinishTargetProcessing()
Definition: Spell.cpp:8469

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), Unit::GetSpellModOwner(), SpellCastTargets::HasDst(), m_caster, m_delayTrajectory, m_immediateHandled, m_targets, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), Player::SetSpellModTakingSpell(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ handle_immediate()

void Spell::handle_immediate ( )
4117{
4118 // start channeling if applicable
4119 if (m_spellInfo->IsChanneled())
4120 {
4121 int32 duration = m_spellInfo->GetDuration();
4123 duration = -1;
4124
4125 if (duration > 0)
4126 {
4127 // First mod_duration then haste - see Missile Barrage
4128 // Apply duration mod
4129 if (Player* modOwner = m_caster->GetSpellModOwner())
4130 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4131
4132 // Apply haste mods
4134 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4135
4138 m_channeledDuration = duration;
4139 SendChannelStart(duration);
4140 }
4141 else if (duration == -1)
4142 {
4145 SendChannelStart(duration);
4146 }
4147 }
4148
4150
4151 // process immediate effects (items, ground, etc.) also initialize some variables
4153
4154 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4155 DoAllEffectOnTarget(&(*ihit));
4156
4157 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4158 DoAllEffectOnTarget(&(*ihit));
4159
4161
4162 // spell is finished, perform some last features of the spell here
4164
4165 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4166 TakeCastItem();
4167
4168 // handle ammo consumption for Hunter's volley spell
4170 TakeAmmo();
4171
4173 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4174}
void AddInterruptMask(uint32 mask)
Definition: Unit.h:1476
void SendChannelStart(uint32 duration)
Definition: Spell.cpp:5207
void TakeAmmo()
Definition: Spell.cpp:5380

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), Unit::GetSpellModOwner(), SpellInfo::HasAttribute(), Unit::HasAuraTypeWithAffectMask(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsChanneled(), SpellInfo::IsRangedWeaponSpell(), m_caster, m_channeledDuration, m_spellInfo, m_spellState, m_UniqueGOTargetInfo, m_UniqueTargetInfo, PrepareTargetProcessing(), SendChannelStart(), SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC, SPELL_AURA_PERIODIC_HASTE, SPELL_STATE_CASTING, SPELLMOD_DURATION, TakeAmmo(), TakeCastItem(), TRIGGERED_IGNORE_EFFECTS, and UNIT_MOD_CAST_SPEED.

Referenced by _cast().

◆ HandleEffects()

void Spell::HandleEffects ( Unit pUnitTarget,
Item pItemTarget,
GameObject pGOTarget,
uint32  i,
SpellEffectHandleMode  mode 
)
5629{
5631 return;
5632
5633 effectHandleMode = mode;
5634 unitTarget = pUnitTarget;
5635 itemTarget = pItemTarget;
5636 gameObjTarget = pGOTarget;
5638
5639 uint8 eff = m_spellInfo->Effects[i].Effect;
5640
5641 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5642
5643 // we do not need DamageMultiplier here.
5644 damage = CalculateSpellDamage(i, nullptr);
5645
5646 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5647
5648 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5649 {
5650 (this->*SpellEffects[eff])((SpellEffIndex)i);
5651 }
5652}
SpellEffIndex
Definition: SharedDefines.h:30
SpellEffects
Definition: SharedDefines.h:778
@ TOTAL_SPELL_EFFECTS
Definition: SharedDefines.h:943
WorldLocation _position
Definition: Spell.h:105
bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode)
Definition: Spell.cpp:8583

References SpellDestination::_position, CalculateSpellDamage(), CallScriptEffectHandlers(), damage, destTarget, effectHandleMode, SpellInfo::Effects, gameObjTarget, HasTriggeredCastFlag(), SpellInfo::Id, itemTarget, LOG_DEBUG, m_destTargets, m_spellInfo, TOTAL_SPELL_EFFECTS, TRIGGERED_IGNORE_EFFECTS, and unitTarget.

Referenced by _handle_immediate_phase(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), and HandleLaunchPhase().

◆ HandleLaunchPhase()

void Spell::HandleLaunchPhase ( )
protected
8233{
8234 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8235 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8236 {
8237 // don't do anything for empty effect
8238 if (!m_spellInfo->Effects[i].IsEffect())
8239 continue;
8240
8241 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8242 }
8243
8244 float multiplier[MAX_SPELL_EFFECTS];
8245 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8246 if (m_applyMultiplierMask & (1 << i))
8247 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8248
8251 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8252 {
8253 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8254 usesAmmo = false;
8255 }
8256
8258
8259 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8260 {
8261 TargetInfo& target = *ihit;
8262
8263 uint32 mask = target.effectMask;
8264 if (!mask)
8265 continue;
8266
8267 // do not consume ammo anymore for Hunter's volley spell
8269 usesAmmo = false;
8270
8271 if (usesAmmo)
8272 {
8273 bool ammoTaken = false;
8274 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8275 {
8276 if (!(mask & 1 << i))
8277 continue;
8278 switch (m_spellInfo->Effects[i].Effect)
8279 {
8285 ammoTaken = true;
8286 TakeAmmo();
8287 }
8288 if (ammoTaken)
8289 break;
8290 }
8291 }
8292
8293 DoAllEffectOnLaunchTarget(target, multiplier);
8294 }
8295
8297}
@ SPELL_EFFECT_SCHOOL_DAMAGE
Definition: SharedDefines.h:780
@ SPELL_ATTR0_CU_DIRECT_DAMAGE
Definition: SpellInfo.h:184
@ SPELL_AURA_ABILITY_CONSUME_NO_AMMO
Definition: SpellAuraDefines.h:337
void DoAllEffectOnLaunchTarget(TargetInfo &targetInfo, float *multiplier)
Definition: Spell.cpp:8299

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::IsTargetingArea(), IsTriggered(), m_applyMultiplierMask, m_caster, m_originalCaster, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, PrepareTargetProcessing(), SPELL_ATTR0_CU_DIRECT_DAMAGE, SPELL_AURA_ABILITY_CONSUME_NO_AMMO, SPELL_EFFECT_HANDLE_LAUNCH, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE, SPELLFAMILY_HUNTER, SpellInfo::SpellFamilyName, and TakeAmmo().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5582{
5583 if (m_UniqueTargetInfo.empty())
5584 return;
5585
5587 return;
5588
5589 float threat = 0.0f;
5590 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5591 {
5592 if (threatEntry->apPctMod != 0.0f)
5593 threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
5594
5595 threat += threatEntry->flatMod;
5596 }
5598 threat += m_spellInfo->SpellLevel;
5599
5600 // past this point only multiplicative effects occur
5601 if (threat == 0.0f)
5602 return;
5603
5604 // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
5605 threat /= m_UniqueTargetInfo.size();
5606
5607 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5608 {
5609 float threatToAdd = threat;
5610 if (ihit->missCondition != SPELL_MISS_NONE)
5611 threatToAdd = 0.0f;
5612
5613 Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
5614 if (!target)
5615 continue;
5616
5617 bool IsFriendly = m_caster->IsFriendlyTo(target);
5618 // positive spells distribute threat among all units that are in combat with target, like healing
5620 target->getHostileRefMgr().threatAssist(m_caster, threatToAdd, m_spellInfo);
5621 // for negative spells threat gets distributed among affected targets
5622 else if (!m_spellInfo->_IsPositiveSpell() && !IsFriendly && target->CanHaveThreatList())
5623 target->AddThreat(m_caster, threatToAdd, m_spellInfo->GetSchoolMask(), m_spellInfo);
5624 }
5625 LOG_DEBUG("spells.aura", "Spell {}, added an additional {} threat for {} {} target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
5626}
static bool IsFriendly(Creature *piece, Creature *target)
Definition: boss_chess_event.cpp:180
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition: SpellInfo.h:180
bool _IsPositiveSpell() const
Definition: SpellInfo.cpp:2840
Definition: SpellMgr.h:385

References SpellInfo::_IsPositiveSpell(), Unit::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), Unit::getHostileRefMgr(), SpellInfo::GetSchoolMask(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, IsFriendly(), Unit::IsFriendlyTo(), LOG_DEBUG, m_caster, m_spellInfo, m_UniqueTargetInfo, SPELL_ATTR0_CU_NO_INITIAL_THREAT, SPELL_ATTR1_NO_THREAT, SPELL_ATTR3_SUPPRESS_TARGET_PROCS, SPELL_MISS_NONE, SpellInfo::SpellLevel, sSpellMgr, and HostileRefMgr::threatAssist().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8103{
8104 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8105 if (itr->effectMask & (1 << effect))
8106 return true;
8107
8108 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8109 if (itr->effectMask & (1 << effect))
8110 return true;
8111
8112 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8113 if (itr->effectMask & (1 << effect))
8114 return true;
8115
8116 return false;
8117}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8475{
8476 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8477 if (!m_effectExecuteData[effIndex])
8478 {
8479 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8480 // first dword - target counter
8481 *m_effectExecuteData[effIndex] << uint32(1);
8482 }
8483 else
8484 {
8485 // increase target counter by one
8486 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8487 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8488 }
8489}

References ASSERT, m_effectExecuteData, and MAX_SPELL_EFFECTS.

Referenced by ExecuteLogEffectCreateItem(), ExecuteLogEffectDestroyItem(), ExecuteLogEffectDurabilityDamage(), ExecuteLogEffectExtraAttacks(), ExecuteLogEffectInterruptCast(), ExecuteLogEffectOpenLock(), ExecuteLogEffectResurrect(), ExecuteLogEffectSummonObject(), ExecuteLogEffectTakeTargetPower(), and ExecuteLogEffectUnsummonObject().

◆ InitExplicitTargets()

void Spell::InitExplicitTargets ( SpellCastTargets const &  targets)
714{
715 m_targets = targets;
716 // this function tries to correct spell explicit targets for spell
717 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
718 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
719 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
720
721 if (WorldObject* target = m_targets.GetObjectTarget())
722 {
723 // check if object target is valid with needed target flags
724 // for unit case allow corpse target mask because player with not released corpse is a unit target
725 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
726 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
727 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
729 }
730 else
731 {
732 // try to select correct unit target if not provided by client or by serverside cast
733 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
734 {
735 Unit* unit = nullptr;
736 // try to use player selection as a target
737 if (Player* playerCaster = m_caster->ToPlayer())
738 {
739 // selection has to be found and to be valid target for the spell
740 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
742 unit = selectedUnit;
743 }
744 // try to use attacked unit as a target
745 else if ((m_caster->IsCreature()) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
746 unit = m_caster->GetVictim();
747
748 // didn't find anything - let's use self as target
749 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
750 unit = m_caster;
751
753 }
754 }
755
756 // check if spell needs dst target
757 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
758 {
759 // and target isn't set
760 if (!m_targets.HasDst())
761 {
762 // try to use unit target if provided
763 if (WorldObject* target = targets.GetObjectTarget())
764 m_targets.SetDst(*target);
765 // or use self if not available
766 else
768 }
769 }
770 else
772
773 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
774 {
775 if (!targets.HasSrc())
777 }
778 else
780}
@ TARGET_FLAG_UNIT_RAID
Definition: SpellInfo.h:48
@ TARGET_FLAG_UNIT_ALLY
Definition: SpellInfo.h:54
@ TARGET_FLAG_SOURCE_LOCATION
Definition: SpellInfo.h:51
@ TARGET_FLAG_CORPSE_MASK
Definition: SpellInfo.h:71
@ TARGET_FLAG_UNIT_PARTY
Definition: SpellInfo.h:49
void RemoveObjectTarget()
Definition: Spell.cpp:321
void RemoveDst()
Definition: Spell.cpp:448
void RemoveSrc()
Definition: Spell.cpp:391

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), Unit::GetTarget(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), Object::IsCreature(), m_caster, m_spellInfo, m_targets, SpellCastTargets::RemoveDst(), SpellCastTargets::RemoveObjectTarget(), SpellCastTargets::RemoveSrc(), SpellCastTargets::SetDst(), SpellCastTargets::SetSrc(), SpellCastTargets::SetUnitTarget(), SPELL_CAST_OK, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_DEST_LOCATION, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_SOURCE_LOCATION, TARGET_FLAG_UNIT, TARGET_FLAG_UNIT_ALLY, TARGET_FLAG_UNIT_ENEMY, TARGET_FLAG_UNIT_MASK, TARGET_FLAG_UNIT_PARTY, TARGET_FLAG_UNIT_RAID, and Object::ToPlayer().

Referenced by Player::CastItemUseSpell(), and prepare().

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8077{
8080 {
8081 return false;
8082 }
8083
8085 {
8086 return false;
8087 }
8088
8089 return true;
8090}
@ SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT
Definition: SharedDefines.h:629

References SpellInfo::HasAttribute(), SpellInfo::InterruptFlags, IsTriggered(), m_casttime, m_spellInfo, SPELL_ATTR6_DOESNT_RESET_SWING_TIMER_IF_INSTANT, and SPELL_INTERRUPT_FLAG_INTERRUPT.

Referenced by _cast().

◆ IsAutoRepeat()

bool Spell::IsAutoRepeat ( ) const
inline

◆ IsChannelActive()

bool Spell::IsChannelActive ( ) const
inline
@ UNIT_CHANNEL_SPELL
Definition: UpdateFields.h:94

References Object::GetUInt32Value(), m_caster, and UNIT_CHANNEL_SPELL.

Referenced by Creature::IsMovementPreventedByCasting().

◆ isDelayableNoMore()

bool Spell::isDelayableNoMore ( )
inlineprotected
631 {
632 if (m_delayAtDamageCount >= 2)
633 return true;
634
636 return false;
637 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
562{ return !m_executedCurrently; }

References m_executedCurrently.

Referenced by Unit::InterruptSpell().

◆ IsNeedSendToClient()

◆ IsNextMeleeSwingSpell()

bool Spell::IsNextMeleeSwingSpell ( ) const

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8225{
8226 if (target->IsAlive())
8228
8230}
bool IsRequiringDeadTarget() const
Definition: SpellInfo.cpp:1222
bool IsAllowingDeadTarget() const
Definition: SpellInfo.cpp:1227

References Unit::IsAlive(), SpellInfo::IsAllowingDeadTarget(), SpellInfo::IsRequiringDeadTarget(), and m_spellInfo.

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8498{
8499 if (_scriptsLoaded)
8500 return;
8501 _scriptsLoaded = true;
8502 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8503 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8504 {
8505 if (!(*itr)->_Load(this))
8506 {
8507 std::list<SpellScript*>::iterator bitr = itr;
8508 ++itr;
8509 delete (*bitr);
8510 m_loadedScripts.erase(bitr);
8511 continue;
8512 }
8513 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8514 (*itr)->Register();
8515 ++itr;
8516 }
8517}

References _scriptsLoaded, SpellInfo::Id, LOG_DEBUG, m_loadedScripts, m_spellInfo, and sScriptMgr.

Referenced by WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), prepare(), and PetAI::UpdateAI().

◆ OnSpellLaunch()

void Spell::OnSpellLaunch ( )
8903{
8904 if (!m_caster || !m_caster->IsInWorld())
8905 return;
8906
8907 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
8908
8909 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
8910 // can succeed with a lockId of 0
8911 if (m_spellInfo->Id == 21651)
8912 {
8913 if (GameObject* go = m_targets.GetGOTarget())
8914 {
8915 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
8916 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
8917 {
8918 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
8919 visual->prepare(&m_targets);
8920 }
8921 }
8922 }
8923}
@ LOCKTYPE_SLOW_OPEN
Definition: SharedDefines.h:2608
@ TRIGGERED_NONE
Definition: SpellDefines.h:130

References SpellCastTargets::GetGOTarget(), SpellInfo::Id, LockEntry::Index, Object::IsInWorld(), LOCKTYPE_SLOW_OPEN, m_caster, m_spellInfo, m_targets, prepare(), sLockStore, sSpellMgr, and TRIGGERED_NONE.

Referenced by prepare().

◆ prepare()

SpellCastResult Spell::prepare ( SpellCastTargets const *  targets,
AuraEffect const *  triggeredByAura = nullptr 
)

m_castItemGUID &&

3477{
3478 if (m_CastItem)
3479 {
3481 }
3482 else
3483 {
3485 }
3486
3487 InitExplicitTargets(*targets);
3488
3489 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3490 {
3491 finish(false);
3492 return SPELL_FAILED_UNKNOWN;
3493 }
3494
3495 // Fill aura scaling information
3497 {
3498 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3499 {
3500 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3503 {
3504 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3506 {
3507 m_auraScaleMask |= (1 << i);
3508 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3509 {
3510 m_auraScaleMask = 0;
3511 break;
3512 }
3513 }
3514 }
3515 }
3516 }
3517
3519
3520 if (triggeredByAura)
3521 {
3522 m_triggeredByAuraSpell.Init(triggeredByAura);
3523 }
3524
3525 // create and add update event for this spell
3526 _spellEvent = new SpellEvent(this);
3528
3530 {
3532 finish(false);
3534 }
3535
3536 //Prevent casting at cast another spell (ServerSide check)
3538 {
3540 finish(false);
3542 }
3543
3544 LoadScripts();
3545
3546 OnSpellLaunch();
3547
3549
3550 // Set combo point requirement
3552 m_needComboPoints = false;
3553
3554 SpellCastResult result = CheckCast(true);
3555 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3556 {
3557 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3558 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3559 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3560 // a possible alternative sollution for those would be validating aura target on unit state change
3561 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3562 {
3564 triggeredByAura->GetBase()->SetDuration(0);
3565 }
3566
3567 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3569 {
3570 SendCastResult(result);
3571
3572 finish(false);
3573 return result;
3574 }
3575 }
3576
3577 // Prepare data for triggers
3578 prepareDataForTriggerSystem(triggeredByAura);
3579
3580 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3582
3583 if (m_caster->IsPlayer())
3585 m_casttime = 0;
3586
3587 // don't allow channeled spells / spells with cast time to be casted while moving
3588 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3590 {
3591 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3593 {
3595 finish(false);
3596 return SPELL_FAILED_MOVING;
3597 }
3598 }
3599
3600 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3601 if (m_CastItem)
3602 {
3603 bool selectTargets = false;
3604 bool nearbyDest = false;
3605
3606 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3607 {
3608 if (!m_spellInfo->Effects[i].IsEffect())
3609 continue;
3610
3611 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3612 {
3613 selectTargets = false;
3614 break;
3615 }
3616
3617 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3618 {
3619 nearbyDest = true;
3620 }
3621
3622 // xinef: by default set it to false, and to true if any valid target is found
3623 selectTargets = true;
3624 }
3625
3626 if (selectTargets)
3627 {
3629 _spellTargetsSelected = true;
3630 bool spellFailed = false;
3631
3632 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3633 {
3634 // no valid nearby target unit or game object found; check if nearby destination type
3635 if (nearbyDest)
3636 {
3637 if (!m_targets.HasDst())
3638 {
3639 // no valid target destination
3640 spellFailed = true;
3641 }
3642 }
3643 else
3644 {
3645 spellFailed = true;
3646 }
3647 }
3648
3649 if (spellFailed)
3650 {
3652 finish(false);
3654 }
3655 }
3656 }
3657
3658 // set timer base at cast time
3659 ReSetTimer();
3660
3661 LOG_DEBUG("spells.aura", "Spell::prepare: spell id {} source {} caster {} customCastFlags {} mask {}", m_spellInfo->Id, m_caster->GetEntry(), m_originalCaster ? m_originalCaster->GetEntry() : -1, _triggeredCastFlags, m_targets.GetTargetMask());
3662
3664 {
3666 }
3667
3668 //Containers for channeled spells have to be set
3669 //TODO:Apply this to all casted spells if needed
3670 // Why check duration? 29350: channelled triggers channelled
3672 cast(true);
3673 else
3674 {
3675 // stealth must be removed at cast starting (at show channel bar)
3676 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3678 {
3679 // Farsight spells exception
3680 uint32 exceptSpellId = 0;
3682 {
3683 exceptSpellId = m_spellInfo->Id;
3684 }
3685
3688 }
3689
3692
3693 // set target for proper facing
3695 {
3698 {
3699 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3700 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3702 }
3703 }
3704
3705 //item: first cast may destroy item and second cast causes crash
3706 // xinef: removed !m_spellInfo->StartRecoveryTime
3707 // second los check failed in events
3708 // xinef: removed itemguid check, currently there is no such item in database
3710 cast(true);
3711
3714 }
3715
3716 return SPELL_CAST_OK;
3717}
@ SPELL_EFFECT_APPLY_AREA_AURA_PARTY
Definition: SharedDefines.h:813
@ SPELL_EFFECT_APPLY_AREA_AURA_RAID
Definition: SharedDefines.h:843
@ SPELL_ATTR0_ALLOW_WHILE_SITTING
Definition: SharedDefines.h:409
@ TARGET_SELECT_CATEGORY_NEARBY
Definition: SpellInfo.h:80
@ TARGET_OBJECT_TYPE_DEST
Definition: SpellInfo.h:100
@ AURA_INTERRUPT_FLAG_SPELL_ATTACK
Definition: SpellDefines.h:56
@ AURA_INTERRUPT_FLAG_CAST
Definition: SpellDefines.h:45
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition: SpellDefines.h:135
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:139
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition: SpellDefines.h:137
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition: SpellDefines.h:26
@ CHEAT_CASTTIME
Definition: Player.h:1000
void FocusTarget(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3549
void SetCurrentCastedSpell(Spell *pSpell)
Definition: Unit.cpp:3957
bool IsSitState() const
Definition: Unit.cpp:16707
Definition: Spell.cpp:519
void Init(AuraEffect const *aurEff)
Definition: Spell.cpp:8925
void LoadScripts()
Definition: Spell.cpp:8497
void cast(bool skipCheck=false)
Definition: Spell.cpp:3790
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition: Spell.cpp:2291
void SendSpellStart()
Definition: Spell.cpp:4718
void TriggerGlobalCooldown()
Definition: Spell.cpp:8841
void OnSpellLaunch()
Definition: Spell.cpp:8902
CurrentSpellTypes GetCurrentContainer() const
Definition: Spell.cpp:7912
void ReSetTimer()
Definition: Spell.h:552
void InitExplicitTargets(SpellCastTargets const &targets)
Definition: Spell.cpp:713
bool IsActionAllowedChannel() const
Definition: SpellInfo.cpp:1261
int32 GetMaxDuration() const
Definition: SpellInfo.cpp:2345
uint32 Attributes
Definition: SpellInfo.h:324
bool IsBreakingStealth() const
Definition: SpellInfo.cpp:1271

References _spellEvent, _spellTargetsSelected, _triggeredCastFlags, EventProcessor::AddEvent(), SpellInfo::Attributes, AURA_INTERRUPT_FLAG_CAST, AURA_INTERRUPT_FLAG_NOT_SEATED, AURA_INTERRUPT_FLAG_SPELL_ATTACK, SpellInfo::AuraInterruptFlags, SpellInfo::CalcCastTime(), SpellInfo::CalcPowerCost(), EventProcessor::CalculateTime(), cast(), CHEAT_CASTTIME, CheckCast(), CURRENT_GENERIC_SPELL, DISABLE_TYPE_SPELL, EFFECT_0, SpellValue::EffectBasePoints, SpellInfo::Effects, ObjectGuid::Empty, finish(), Creature::FocusTarget(), AuraEffect::GetBase(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetTargetMask(), SpellCastTargets::HasDst(), SpellInfo::HasEffect(), HasTriggeredCastFlag(), SpellInfo::Id, TriggeredByAuraSpellData::Init(), InitExplicitTargets(), SpellInfo::InterruptFlags, SpellInfo::IsActionAllowedChannel(), IsAutoRepeat(), SpellInfo::IsBreakingStealth(), SpellInfo::IsChanneled(), Unit::IsControlledByPlayer(), Object::IsCreature(), DisableMgr::IsDisabledFor(), Creature::IsInEvadeMode(), Unit::isMoving(), IsNextMeleeSwingSpell(), Unit::IsNonMeleeSpellCast(), Aura::IsPassive(), SpellInfo::IsPassive(), AuraEffect::IsPeriodic(), Object::IsPlayer(), SpellInfo::IsPositive(), SpellInfo::IsPositiveEffect(), Unit::IsSitState(), Unit::IsTotem(), IsTriggered(), LoadScripts(), LOG_DEBUG, m_auraScaleMask, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_casttime, Unit::m_Events, m_needComboPoints, m_originalCaster, m_powerCost, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_targets, m_triggeredByAuraSpell, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, OnSpellLaunch(), prepareDataForTriggerSystem(), Unit::RemoveAurasWithInterruptFlags(), ReSetTimer(), SelectSpellTargets(), SendCastResult(), SendChannelUpdate(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Aura::SetDuration(), Unit::SetStandState(), SPELL_ATTR0_ALLOW_WHILE_SITTING, SPELL_CAST_OK, SPELL_EFFECT_ADD_FARSIGHT, SPELL_EFFECT_APPLY_AREA_AURA_PARTY, SPELL_EFFECT_APPLY_AREA_AURA_RAID, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_MOVING, SPELL_FAILED_OUT_OF_RANGE, SPELL_FAILED_SPELL_IN_PROGRESS, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_UNKNOWN, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_PREPARING, SpellInfo::SpellLevel, sScriptMgr, TARGET_CHECK_ENTRY, TARGET_OBJECT_TYPE_DEST, TARGET_SELECT_CATEGORY_NEARBY, Object::ToCreature(), Object::ToPlayer(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS, TRIGGERED_IGNORE_AURA_SCALING, TRIGGERED_IGNORE_CAST_IN_PROGRESS, TRIGGERED_IGNORE_COMBO_POINTS, TRIGGERED_IGNORE_GCD, TRIGGERED_IGNORE_SET_FACING, TriggerGlobalCooldown(), and UNIT_STAND_STATE_STAND.

Referenced by Unit::_UpdateAutoRepeatSpell(), Player::CastItemUseSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2292{
2293 //==========================================================================================
2294 // Now fill data for trigger system, need know:
2295 // can spell trigger another or not (m_canTrigger)
2296 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2297 //==========================================================================================
2298
2300 // Get data for type of attack and fill base info for trigger
2301 switch (m_spellInfo->DmgClass)
2302 {
2305 if (m_attackType == OFF_ATTACK)
2307 else
2310 break;
2312 // Auto attack
2314 {
2317 }
2318 else // Ranged spell attack
2319 {
2322 }
2323 break;
2324 default:
2327 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2328 {
2331 }
2332 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2333 // Because spell positivity is dependant on target
2334 }
2336
2337 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2339 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2340 m_spellInfo->Id == 57879 || m_spellInfo->Id == 45145 || // Snake Trap - done this way to avoid double proc
2341 m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap
2342 {
2344 }
2345
2346 /* Effects which are result of aura proc from triggered spell cannot proc
2347 to prevent chain proc of these spells */
2348
2349 // Hellfire Effect - trigger as DOT
2351 {
2354 }
2355
2356 // Ranged autorepeat attack is set as triggered spell - ignore it
2358 {
2365 }
2366 // Totem casts require spellfamilymask defined in spell_proc_event to proc
2369}
@ SPELL_ATTR2_ACTIVE_THREAT
Definition: SharedDefines.h:486
@ SPELL_ATTR3_NOT_A_PROC
Definition: SharedDefines.h:502
@ TRIGGERED_DISALLOW_PROC_EVENTS
Will ignore caster aura restrictions or requirements.
Definition: SpellDefines.h:145
@ PROC_EX_NONE
Definition: SpellMgr.h:193
@ PROC_EX_INTERNAL_CANT_PROC
Definition: SpellMgr.h:218
@ PROC_EX_INTERNAL_TRIGGERED
Definition: SpellMgr.h:221
@ PROC_EX_INTERNAL_REQ_FAMILY
Definition: SpellMgr.h:222
@ PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:119
@ PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:117
@ PROC_FLAG_DONE_PERIODIC
Definition: SpellMgr.h:134
@ PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:113
@ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS
Definition: SpellMgr.h:120
@ PROC_FLAG_TAKEN_PERIODIC
Definition: SpellMgr.h:135
@ PROC_FLAG_DONE_MAINHAND_ATTACK
Definition: SpellMgr.h:140
@ PROC_FLAG_DONE_RANGED_AUTO_ATTACK
Definition: SpellMgr.h:116
@ PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS
Definition: SpellMgr.h:114
@ PROC_FLAG_DONE_TRAP_ACTIVATION
Definition: SpellMgr.h:138
@ PROC_FLAG_DONE_OFFHAND_ATTACK
Definition: SpellMgr.h:141

References SpellInfo::DmgClass, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, SpellInfo::HasAttribute(), HasTriggeredCastFlag(), SpellInfo::Id, Unit::IsControlledByPlayer(), Object::IsCreature(), Unit::IsTotem(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, m_originalCaster, m_procAttacker, m_procEx, m_procVictim, m_spellInfo, OFF_ATTACK, PROC_EX_INTERNAL_CANT_PROC, PROC_EX_INTERNAL_REQ_FAMILY, PROC_EX_INTERNAL_TRIGGERED, PROC_EX_NONE, PROC_FLAG_DONE_MAINHAND_ATTACK, PROC_FLAG_DONE_OFFHAND_ATTACK, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_DONE_RANGED_AUTO_ATTACK, PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS, PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS, PROC_FLAG_DONE_TRAP_ACTIVATION, PROC_FLAG_TAKEN_PERIODIC, PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK, PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS, PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_ATTR2_ACTIVE_THREAT, SPELL_ATTR2_AUTO_REPEAT, SPELL_ATTR3_NOT_A_PROC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLFAMILY_HUNTER, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, Object::ToCreature(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8578{
8579 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8580 (*scritr)->_InitHit();
8581}

References m_loadedScripts.

Referenced by _cast(), _handle_immediate_phase(), and DoAllEffectOnTarget().

◆ PrepareTargetProcessing()

void Spell::PrepareTargetProcessing ( )
protected

◆ PrepareTriggersExecutedOnHit()

void Spell::PrepareTriggersExecutedOnHit ( )
protected
Todo:
: move this to scripts
Todo:
: move this to scripts
8752{
8755 {
8756 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8757 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8759 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8760 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8762 }
8763
8766 {
8768 {
8769 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8770 {
8772 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8773 {
8774 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8775 {
8776 m_preCastSpell = 26017;
8777 break;
8778 }
8779 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8780 m_preCastSpell = 67;
8781 }
8782 }
8783 break;
8784 }
8785 case SPELLFAMILY_DRUID:
8786 {
8787 // Faerie Fire (Feral)
8789 m_preCastSpell = 60089;
8790
8791 break;
8792 }
8793 }
8794
8795 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8796 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8797 // and to correctly calculate proc chance when combopoints are present
8799 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8800 {
8801 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8802 continue;
8803 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8804 uint32 auraSpellIdx = (*i)->GetEffIndex();
8805 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8806 {
8807 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8808 // this possibly needs fixing
8809 int32 auraBaseAmount = (*i)->GetBaseAmount();
8810 // proc chance is stored in effect amount
8811 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8812 // build trigger and add to the list
8813 HitTriggerSpell spellTriggerInfo;
8814 spellTriggerInfo.triggeredSpell = spellInfo;
8815 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8816 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8817 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8818 m_hitTriggerSpells.push_back(spellTriggerInfo);
8819 }
8820 }
8821}
@ SPELL_AURA_PROC_TRIGGER_SPELL
Definition: SpellAuraDefines.h:105
@ SPELL_AURA_ADD_TARGET_TRIGGER
Definition: SpellAuraDefines.h:172
@ FORM_DIREBEAR
Definition: UnitDefines.h:77
@ FORM_BEAR
Definition: UnitDefines.h:74
uint32 ExcludeTargetAuraSpell
Definition: SpellInfo.h:346

References Unit::CalculateSpellDamage(), Spell::HitTriggerSpell::chance, EFFECT_0, SpellInfo::Effects, SpellInfo::ExcludeCasterAuraSpell, SpellInfo::ExcludeTargetAuraSpell, FORM_BEAR, FORM_DIREBEAR, Unit::GetAuraEffectsByType(), Unit::GetShapeshiftForm(), SpellInfo::Id, SpellInfo::IsPositive(), m_caster, m_hitTriggerSpells, m_preCastSpell, m_spellInfo, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_DRUID, SPELLFAMILY_PALADIN, SpellInfo::SpellFamilyFlags, SpellInfo::SpellFamilyName, sSpellMgr, Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
917{
920}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:27
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition: EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition: Spell.cpp:895
uint64 GetDelayStart() const
Definition: Spell.h:564

References _spellEvent, CalculateDelayMomentForDst(), GetDelayStart(), m_caster, m_delayMoment, Unit::m_Events, and EventProcessor::ModifyEventTime().

◆ ReSetTimer()

void Spell::ReSetTimer ( )
inline
552{ m_timer = m_casttime > 0 ? m_casttime : 0; }

References m_casttime, and m_timer.

Referenced by prepare().

◆ SearchAreaTargets()

void Spell::SearchAreaTargets ( std::list< WorldObject * > &  targets,
float  range,
Position const *  position,
Unit referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList 
)
2186{
2187 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2188 if (!containerTypeMask)
2189 return;
2190 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
2191 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2192 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2193}
Definition: GridNotifiers.h:239
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition: Spell.cpp:2109

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SearchChainTargets(), and SelectImplicitAreaTargets().

◆ SearchChainTargets()

void Spell::SearchChainTargets ( std::list< WorldObject * > &  targets,
uint32  chainTargets,
WorldObject target,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectType,
SpellTargetSelectionCategories  selectCategory,
ConditionList condList,
bool  isChainHeal 
)
2196{
2197 // max dist for jump target selection
2198 float jumpRadius = 0.0f;
2199 switch (m_spellInfo->DmgClass)
2200 {
2202 // 7.5y for multi shot
2203 jumpRadius = 7.5f;
2204 break;
2206 // 5y for swipe, cleave and similar
2207 jumpRadius = 5.0f;
2208 break;
2211 // 12.5y for chain heal spell since 3.2 patch
2212 if (isChainHeal)
2213 jumpRadius = 12.5f;
2214 // 10y as default for magic chain spells
2215 else
2216 jumpRadius = 10.0f;
2217 break;
2218 }
2219
2220 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2224
2225 // max dist which spell can reach
2226 float searchRadius = jumpRadius;
2227 if (isBouncingFar)
2228 searchRadius *= chainTargets;
2229
2230 std::list<WorldObject*> tempTargets;
2231 SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
2232 tempTargets.remove(target);
2233
2234 // remove targets which are always invalid for chain spells
2235 // for some spells allow only chain targets in front of caster (swipe for example)
2236 if (!isBouncingFar)
2237 {
2238 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
2239 {
2240 std::list<WorldObject*>::iterator checkItr = itr++;
2241 if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
2242 tempTargets.erase(checkItr);
2243 }
2244 }
2245
2246 while (chainTargets)
2247 {
2248 // try to get unit for next chain jump
2249 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2250 // get unit with highest hp deficit in dist
2251 if (isChainHeal)
2252 {
2253 uint32 maxHPDeficit = 0;
2254 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2255 {
2256 if (Unit* unit = (*itr)->ToUnit())
2257 {
2258 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2259 if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2260 {
2261 foundItr = itr;
2262 maxHPDeficit = deficit;
2263 }
2264 }
2265 }
2266 }
2267 // get closest object
2268 else
2269 {
2270 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2271 {
2272 if (foundItr == tempTargets.end())
2273 {
2274 if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2275 foundItr = itr;
2276 }
2277 else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2278 foundItr = itr;
2279 }
2280 }
2281 // not found any valid target - chain ends
2282 if (foundItr == tempTargets.end())
2283 break;
2284 target = *foundItr;
2285 tempTargets.erase(foundItr);
2286 targets.push_back(target);
2287 --chainTargets;
2288 }
2289}
@ SPELL_ATTR4_BOUNCY_CHAIN_MISSILES
Definition: SharedDefines.h:548
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1316
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition: Object.cpp:1381
void SearchAreaTargets(std::list< WorldObject * > &targets, float range, Position const *position, Unit *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList)
Definition: Spell.cpp:2185

References SpellInfo::DmgClass, WorldObject::GetDistanceOrder(), SpellInfo::HasAttribute(), Position::HasInArc(), WorldObject::IsWithinDist(), WorldObject::IsWithinLOSInMap(), VMAP::M2, m_caster, m_spellInfo, SearchAreaTargets(), SPELL_ATTR4_BOUNCY_CHAIN_MISSILES, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_NONE, SPELL_DAMAGE_CLASS_RANGED, and Object::ToUnit().

Referenced by SelectImplicitChainTargets().

◆ SearchNearbyTarget()

WorldObject * Spell::SearchNearbyTarget ( float  range,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList condList = nullptr 
)
2174{
2175 WorldObject* target = nullptr;
2176 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2177 if (!containerTypeMask)
2178 return nullptr;
2179 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2181 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2182 return target;
2183}
Definition: GridNotifiers.h:219

References GetSearcherTypeMask(), m_caster, and m_spellInfo.

Referenced by SelectImplicitNearbyTargets().

◆ SearchTargets()

template<class SEARCHER >
void Spell::SearchTargets ( SEARCHER &  searcher,
uint32  containerMask,
Unit referer,
Position const *  pos,
float  radius 
)
2145{
2146 if (!containerMask)
2147 return;
2148
2149 // search world and grid for possible targets
2150 bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
2151 bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
2152
2153 if (searchInGrid || searchInWorld)
2154 {
2155 float x, y;
2156 x = pos->GetPositionX();
2157 y = pos->GetPositionY();
2158
2160 Cell cell(p);
2161 cell.SetNoCreate();
2162
2163 Map* map = referer->GetMap();
2164
2165 if (searchInWorld)
2166 Cell::VisitWorldObjects(x, y, map, searcher, radius);
2167
2168 if (searchInGrid)
2169 Cell::VisitGridObjects(x, y, map, searcher, radius);
2170 }
2171}
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:178

References Acore::ComputeCellCoord(), WorldObject::GetMap(), Position::GetPositionX(), Position::GetPositionY(), GRID_MAP_TYPE_MASK_CORPSE, GRID_MAP_TYPE_MASK_CREATURE, GRID_MAP_TYPE_MASK_GAMEOBJECT, GRID_MAP_TYPE_MASK_PLAYER, Cell::SetNoCreate(), Cell::VisitGridObjects(), and Cell::VisitWorldObjects().

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
923{
924 if (!targetType.GetTarget())
925 return;
926
927 uint32 effectMask = 1 << effIndex;
928 // set the same target list for all effects
929 // some spells appear to need this, however this requires more research
930 switch (targetType.GetSelectionCategory())
931 {
935 {
936 // targets for effect already selected
937 if (effectMask & processedEffectMask)
938 {
939 return;
940 }
941
942 auto const& effects = GetSpellInfo()->Effects;
943
944 // choose which targets we can select at once
945 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
946 {
947 if (effects[j].IsEffect() &&
948 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
949 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
950 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
951 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
953 {
954 effectMask |= 1 << j;
955 }
956 }
957 processedEffectMask |= effectMask;
958 break;
959 }
960 default:
961 break;
962 }
963
964 switch (targetType.GetSelectionCategory())
965 {
967 SelectImplicitChannelTargets(effIndex, targetType);
968 break;
970 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
971 break;
973 SelectImplicitConeTargets(effIndex, targetType, effectMask);
974 break;
976 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
977 break;
979 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
980 CheckDst();
981
982 SelectImplicitTrajTargets(effIndex, targetType);
983 break;
985 switch (targetType.GetObjectType())
986 {
988 switch (targetType.GetReferenceType())
989 {
992 break;
993 default:
994 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
995 break;
996 }
997 break;
999 switch (targetType.GetReferenceType())
1000 {
1002 SelectImplicitCasterDestTargets(effIndex, targetType);
1003 break;
1005 SelectImplicitTargetDestTargets(effIndex, targetType);
1006 break;
1008 SelectImplicitDestDestTargets(effIndex, targetType);
1009 break;
1010 default:
1011 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1012 break;
1013 }
1014 break;
1015 default:
1016 switch (targetType.GetReferenceType())
1017 {
1019 SelectImplicitCasterObjectTargets(effIndex, targetType);
1020 break;
1022 SelectImplicitTargetObjectTargets(effIndex, targetType);
1023 break;
1024 default:
1025 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1026 break;
1027 }
1028 break;
1029 }
1030 break;
1032 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1033 break;
1034 default:
1035 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1036 break;
1037 }
1038}
@ TARGET_SELECT_CATEGORY_CONE
Definition: SpellInfo.h:81
@ TARGET_SELECT_CATEGORY_AREA
Definition: SpellInfo.h:82
@ TARGET_SELECT_CATEGORY_DEFAULT
Definition: SpellInfo.h:78
@ TARGET_SELECT_CATEGORY_NYI
Definition: SpellInfo.h:77
@ TARGET_SELECT_CATEGORY_TRAJ
Definition: SpellInfo.h:83
@ TARGET_SELECT_CATEGORY_CHANNEL
Definition: SpellInfo.h:79
@ TARGET_OBJECT_TYPE_SRC
Definition: SpellInfo.h:99
@ TARGET_REFERENCE_TYPE_TARGET
Definition: SpellInfo.h:90
@ TARGET_REFERENCE_TYPE_CASTER
Definition: SpellInfo.h:89
@ TARGET_REFERENCE_TYPE_DEST
Definition: SpellInfo.h:93
void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1717
void CheckDst()
Definition: Spell.h:494
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1866
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1210
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1680
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1260
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1040
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1803
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1756
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition: Spell.cpp:1096
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition: Spell.cpp:8712
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:1342

References ASSERT, CheckDst(), CheckScriptEffectImplicitTargets(), SpellInfo::Effects, SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetSelectionCategory(), GetSpellInfo(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAX_SPELL_EFFECTS, SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SpellCastTargets::SetSrc(), TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CATEGORY_NYI, and TARGET_SELECT_CATEGORY_TRAJ.

Referenced by SelectSpellTargets().

◆ SelectEffectTypeImplicitTargets()

void Spell::SelectEffectTypeImplicitTargets ( uint8  effIndex)
Todo:
: this is a workaround - target shouldn't be stored in target map for those spells
Todo:
: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
2027{
2028 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2030 switch (m_spellInfo->Effects[effIndex].Effect)
2031 {
2035 {
2037
2039
2040 if (target && target->ToPlayer())
2041 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2042 }
2043 return;
2044 default:
2045 break;
2046 }
2047
2048 // select spell implicit targets based on effect type
2049 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2050 return;
2051
2052 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2053
2054 if (!targetMask)
2055 return;
2056
2057 WorldObject* target = nullptr;
2058
2059 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2060 {
2061 // add explicit object target or self to the target map
2063 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2065 {
2067 target = unitTarget;
2068 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2069 {
2070 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2071 {
2073 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2074 target = owner;
2075 }
2076 }
2077 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2078 target = m_caster;
2079 }
2080 if (targetMask & TARGET_FLAG_ITEM_MASK)
2081 {
2083 AddItemTarget(itemTarget, 1 << effIndex);
2084 return;
2085 }
2086 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2087 target = m_targets.GetGOTarget();
2088 break;
2089 // add self to the target map
2091 if (targetMask & TARGET_FLAG_UNIT_MASK)
2092 target = m_caster;
2093 break;
2094 default:
2095 break;
2096 }
2097
2099
2100 if (target)
2101 {
2102 if (target->ToUnit())
2103 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2104 else if (target->ToGameObject())
2105 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2106 }
2107}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition: SpellInfo.h:144
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition: SpellInfo.h:143
@ TARGET_FLAG_ITEM_MASK
Definition: SpellInfo.h:72
GameObject * ToGameObject()
Definition: Object.h:210
Corpse * GetCorpseTarget() const
Definition: Spell.cpp:294
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition: Spell.cpp:2513
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition: Spell.cpp:2380
void AddItemTarget(Item *item, uint32 effectMask)
Definition: Spell.cpp:2575
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8684
Definition: SpellInfo.h:217

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), EFFECT_IMPLICIT_TARGET_CASTER, EFFECT_IMPLICIT_TARGET_EXPLICIT, SpellInfo::Effects, ObjectAccessor::FindPlayer(), SpellCastTargets::GetCorpseTarget(), SpellCastTargets::GetGOTarget(), SpellCastTargets::GetItemTarget(), Unit::GetTarget(), SpellCastTargets::GetUnitTarget(), Object::IsPlayer(), itemTarget, m_caster, m_spellInfo, m_targets, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_SUMMON_RAF_FRIEND, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_GAMEOBJECT_MASK, TARGET_FLAG_ITEM_MASK, TARGET_FLAG_UNIT_MASK, Object::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), and unitTarget.

Referenced by SelectSpellTargets().

◆ SelectExplicitTargets()

void Spell::SelectExplicitTargets ( )
783{
784 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
785 if (Unit* target = m_targets.GetUnitTarget())
786 {
787 // check for explicit target redirection, for Grounding Totem for example
791 {
792 Unit* redirect;
793 switch (m_spellInfo->DmgClass)
794 {
797 break;
801 break;
802 default:
803 redirect = nullptr;
804 break;
805 }
806 if (redirect && (redirect != target))
807 {
808 m_targets.SetUnitTarget(redirect);
810 }
811 }
812 }
813}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition: Unit.cpp:11052
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition: Unit.cpp:11014

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), Unit::GetMagicHitRedirectTarget(), Unit::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), Unit::IsFriendlyTo(), SpellInfo::IsPositive(), m_caster, m_spellFlags, m_spellInfo, m_targets, SpellCastTargets::SetUnitTarget(), SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_EFFECT_DISPEL, SPELL_FLAG_REDIRECTED, TARGET_FLAG_UNIT, and TARGET_FLAG_UNIT_ENEMY.

Referenced by SelectSpellTargets().

◆ SelectImplicitAreaTargets()

void Spell::SelectImplicitAreaTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1261{
1262 Unit* referer = nullptr;
1263 switch (targetType.GetReferenceType())
1264 {
1268 referer = m_caster;
1269 break;
1271 referer = m_targets.GetUnitTarget();
1272 break;
1274 {
1275 // find last added target for this effect
1276 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1277 {
1278 if (ihit->effectMask & (1 << effIndex))
1279 {
1280 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1281 break;
1282 }
1283 }
1284 break;
1285 }
1286 default:
1287 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1288 return;
1289 }
1290 if (!referer)
1291 return;
1292
1293 Position const* center = nullptr;
1294 switch (targetType.GetReferenceType())
1295 {
1297 center = m_targets.GetSrcPos();
1298 break;
1300 center = m_targets.GetDstPos();
1301 break;
1305 center = referer;
1306 break;
1307 default:
1308 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1309 return;
1310 }
1311
1312 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1313 std::list<WorldObject*> targets;
1314 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1315 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1316
1317 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1318
1319 if (!targets.empty())
1320 {
1321 // Other special target selection goes here
1322 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1323 {
1325 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1326 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1327 maxTargets += (*j)->GetAmount();
1328
1329 Acore::Containers::RandomResize(targets, maxTargets);
1330 }
1331
1332 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1333 {
1334 if (Unit* unitTarget = (*itr)->ToUnit())
1335 AddUnitTarget(unitTarget, effMask, false);
1336 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1337 AddGOTarget(gObjTarget, effMask);
1338 }
1339 }
1340}
@ TARGET_REFERENCE_TYPE_SRC
Definition: SpellInfo.h:92
@ TARGET_REFERENCE_TYPE_LAST
Definition: SpellInfo.h:91
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition: SpellAuraDefines.h:340
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:79
Position const * GetSrcPos() const
Definition: Spell.cpp:362
float RadiusMod
Definition: Spell.h:217
uint32 MaxAffectedTargets
Definition: Spell.h:216
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8670

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), ObjectAccessor::GetUnit(), SpellCastTargets::GetUnitTarget(), m_caster, m_spellInfo, m_spellValue, m_targets, m_UniqueTargetInfo, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SearchAreaTargets(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, TARGET_REFERENCE_TYPE_DEST, TARGET_REFERENCE_TYPE_LAST, TARGET_REFERENCE_TYPE_SRC, TARGET_REFERENCE_TYPE_TARGET, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1343{
1345
1346 switch (targetType.GetTarget())
1347 {
1348 case TARGET_DEST_CASTER:
1350 break;
1351 case TARGET_DEST_HOME:
1352 if (Player* playerCaster = m_caster->ToPlayer())
1353 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1354 break;
1355 case TARGET_DEST_DB:
1356 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1357 {
1360 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1361 else if (st->target_mapId == m_caster->GetMapId())
1362 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1363 }
1364 else
1365 {
1366 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1367 if (WorldObject* target = m_targets.GetObjectTarget())
1368 dest = SpellDestination(*target);
1369 }
1370 break;
1372 {
1373 float min_dis = m_spellInfo->GetMinRange(true);
1374 float max_dis = m_spellInfo->GetMaxRange(true);
1375 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1376 float x, y, z, angle;
1377 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1378 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1380
1381 float ground = m_caster->GetMapHeight(x, y, z, true);
1382 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1384 if (liquidData.Status)
1385 liquidLevel = liquidData.Level;
1386
1387 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1388 {
1391 finish(false);
1392 return;
1393 }
1394
1395 if (ground + 0.75 > liquidLevel)
1396 {
1399 finish(false);
1400 return;
1401 }
1402
1403 if (!m_caster->IsWithinLOS(x, y, z))
1404 {
1407 finish(false);
1408 return;
1409 }
1410
1411 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1412 break;
1413 }
1415 {
1416 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1417 Map* map = m_caster->GetMap();
1418 uint32 mapid = m_caster->GetMapId();
1419 uint32 phasemask = m_caster->GetPhaseMask();
1420 float collisionHeight = m_caster->GetCollisionHeight();
1421 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1422
1423 Position pos;
1424 Position lastpos;
1425 m_caster->GetPosition(startx, starty, startz, starto);
1426 pos.Relocate(startx, starty, startz, starto);
1427 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1428 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1429
1430 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
1431
1432 bool isCasterInWater = m_caster->IsInWater();
1433 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1434 {
1435 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1436 float tstZ1 = 0.0f, tstZ2 = 0.0f, tstZ3 = 0.0f, destz1 = 0.0f, destz2 = 0.0f, destz3 = 0.0f, srange = 0.0f, srange1 = 0.0f, srange2 = 0.0f, srange3 = 0.0f;
1437 float maxtravelDistZ = 2.65f;
1438 float overdistance = 0.0f;
1439 float totalpath = 0.0f;
1440 float beforewaterz = 0.0f;
1441 bool inwater = false;
1442 bool wcol = false;
1443 const float step = 2.0f;
1444 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1445 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1446 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1447 int j = 1;
1448 for (; j < (numChecks + 1); j++)
1449 {
1450 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1451 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1452 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1453 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1454
1455 if (j < 2)
1456 {
1457 prevZ = pos.GetPositionZ();
1458 }
1459 else
1460 {
1461 prevZ = tstZ;
1462 }
1463
1464 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1465 ground = tstZ;
1466
1467 if (!isCasterInWater)
1468 {
1469 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1470 {
1471 if (!(beforewaterz != 0.0f))
1472 {
1473 beforewaterz = prevZ;
1474 }
1475 tstZ = beforewaterz;
1476 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1477 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1478 }
1479 }
1480 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1481 {
1482 prevZ = pos.GetPositionZ();
1483 tstZ = pos.GetPositionZ();
1484 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1485
1486 inwater = true;
1487 if (inwater && (fabs(tstZ - ground) < 2.0f))
1488 {
1489 wcol = true;
1490 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1491 }
1492
1493 // if (j < 2)
1494 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1495 // else
1496 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1497 }
1498
1499 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1500 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1501 {
1502 if (inwater && !IsInWater)
1503 inwater = false;
1504
1505 // highest available point
1506 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1507 // upper or floor
1508 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1509 //lower than floor
1510 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1511
1512 //distance of rays, will select the shortest in 3D
1513 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1514 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1515 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1516 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1517 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1518 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1519
1520 if (srange1 < srange2)
1521 {
1522 tstZ = tstZ1;
1523 srange = srange1;
1524 }
1525 else if (srange3 < srange2)
1526 {
1527 tstZ = tstZ3;
1528 srange = srange3;
1529 }
1530 else
1531 {
1532 tstZ = tstZ2;
1533 srange = srange2;
1534 }
1535
1536 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1537 }
1538
1539 destx = tstX;
1540 desty = tstY;
1541 destz = tstZ;
1542
1543 totalpath += srange;
1544
1545 if (totalpath > distance)
1546 {
1547 overdistance = totalpath - distance;
1548 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1549 }
1550
1551 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1552 // check dynamic collision
1553 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1554
1555 // collision occured
1556 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1557 {
1558 if ((overdistance > 0.0f) && (overdistance < 1.f))
1559 {
1560 destx = prevX + overdistance * cos(pos.GetOrientation());
1561 desty = prevY + overdistance * sin(pos.GetOrientation());
1562 //LOG_ERROR("spells", "(collision) collision occured 1");
1563 }
1564 else
1565 {
1566 // move back a bit
1567 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1568 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1569 //LOG_ERROR("spells", "(collision) collision occured 2");
1570 }
1571
1572 // highest available point
1573 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1574 // upper or floor
1575 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1576 //lower than floor
1577 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1578
1579 //distance of rays, will select the shortest in 3D
1580 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1581 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1582 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1583
1584 if (srange1 < srange2)
1585 destz = destz1;
1586 else if (srange3 < srange2)
1587 destz = destz3;
1588 else
1589 destz = destz2;
1590
1591 if (inwater && destz < prevZ && !wcol)
1592 destz = prevZ;
1593 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1594
1595 // Don't make the player move backward from the xy adjustments by collisions.
1596 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1597 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1598 {
1599 destx = startx;
1600 desty = starty;
1601 destz = startz;
1602 }
1603
1604 break;
1605 }
1606 // we have correct destz now
1607 }
1608
1609 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1610 dest = SpellDestination(lastpos);
1611 }
1612 else
1613 {
1614 float z = pos.GetPositionZ();
1615 bool col = VMAP::VMapFactory::createOrGetVMapMgr()->GetObjectHitPos(mapid, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1616 // check dynamic collision
1617 bool dcol = m_caster->GetMap()->GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1618
1619 // collision occured
1620 if (col || dcol)
1621 {
1622 // move back a bit
1623 destx = destx - (0.6 * cos(pos.GetOrientation()));
1624 desty = desty - (0.6 * sin(pos.GetOrientation()));
1625 }
1626
1627 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1628 dest = SpellDestination(lastpos);
1629 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1630 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1631 }
1632 break;
1633 }
1634 default:
1635 {
1636 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1637 float angle = targetType.CalcDirectionAngle();
1638 float objSize = m_caster->GetCombatReach();
1639
1640 switch (targetType.GetTarget())
1641 {
1643 dist = PET_FOLLOW_DIST;
1644 break;
1646 if (dist > objSize)
1647 dist = objSize + (dist - objSize) * float(rand_norm());
1648 break;
1653 {
1654 static float const DefaultTotemDistance = 3.0f;
1655 if (!m_spellInfo->Effects[effIndex].HasRadius())
1656 dist = DefaultTotemDistance;
1657 break;
1658 }
1659 default:
1660 break;
1661 }
1662
1663 if (dist < objSize)
1664 {
1665 dist = objSize;
1666 }
1667
1668 Position pos = dest._position;
1669 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1670
1671 dest.Relocate(pos);
1672 break;
1673 }
1674 }
1675
1676 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1677 m_targets.SetDst(dest);
1678}
#define VMAP_INVALID_HEIGHT_VALUE
Definition: IVMapMgr.h:49
@ SPELL_EFFECT_BIND
Definition: SharedDefines.h:789
@ SPELL_EFFECT_TELEPORT_UNITS
Definition: SharedDefines.h:783
@ TARGET_DEST_CASTER_RANDOM
Definition: SharedDefines.h:1476
@ TARGET_DEST_DB
Definition: SharedDefines.h:1422
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition: SharedDefines.h:1459
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition: SharedDefines.h:1448
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition: SharedDefines.h:1446
@ TARGET_DEST_CASTER_FISHING
Definition: SharedDefines.h:1443
@ TARGET_DEST_CASTER_BACK_LEFT
Definition: SharedDefines.h:1447
@ TARGET_DEST_CASTER_SUMMON
Definition: SharedDefines.h:1436
@ TARGET_DEST_CASTER
Definition: SharedDefines.h:1423
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition: SharedDefines.h:1445
@ TARGET_DEST_CASTER_36
Definition: SharedDefines.h:1440
@ TARGET_DEST_HOME
Definition: SharedDefines.h:1418
@ SPELL_FAILED_TOO_SHALLOW
Definition: SharedDefines.h:1105
#define MAP_ALL_LIQUIDS
Definition: Map.h:158
@ MOVEMENTFLAG_FALLING
Definition: UnitDefines.h:356
static VMapMgr2 * createOrGetVMapMgr()
Definition: VMapFactory.cpp:27
bool GetObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) override
Definition: VMapMgr2.cpp:201
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition: Object.cpp:3120
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition: Object.cpp:2626
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:21102
Definition: Map.h:169
float Level
Definition: Map.h:174
LiquidStatus Status
Definition: Map.h:176
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:2043
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
Definition: Map.cpp:2204
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition: Map.cpp:2503
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition: Map.cpp:2481
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition: Spell.cpp:8698
Definition: SpellMgr.h:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), VMAP::VMapFactory::createOrGetVMapMgr(), DEFAULT_WORLD_OBJECT_SIZE, SpellInfo::Effects, finish(), Unit::GetCollisionHeight(), Unit::GetCombatReach(), Map::GetHeight(), Map::GetLiquidData(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), SpellInfo::GetMinRange(), WorldObject::GetNearPoint(), Map::GetObjectHitPos(), VMAP::VMapMgr2::GetObjectHitPos(), SpellCastTargets::GetObjectTarget(), Position::GetOrientation(), WorldObject::GetPhaseMask(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::HasEffect(), Unit::HasUnitMovementFlag(), SpellInfo::Id, Unit::IsInWater(), Map::IsInWater(), WorldObject::IsWithinLOS(), LiquidData::Level, LOG_DEBUG, m_caster, m_spellInfo, m_targets, MAP_ALL_LIQUIDS, MOVEMENTFLAG_FALLING, WorldObject::MovePositionToFirstCollision(), PET_FOLLOW_DIST, rand_norm(), Position::Relocate(), SpellDestination::Relocate(), SendCastResult(), SendChannelUpdate(), SpellCastTargets::SetDst(), SPELL_EFFECT_BIND, SPELL_EFFECT_TELEPORT_UNITS, SPELL_FAILED_LINE_OF_SIGHT, SPELL_FAILED_NOT_HERE, SPELL_FAILED_TOO_SHALLOW, sSpellMgr, LiquidData::Status, TARGET_DEST_CASTER, TARGET_DEST_CASTER_36, TARGET_DEST_CASTER_BACK_LEFT, TARGET_DEST_CASTER_BACK_RIGHT, TARGET_DEST_CASTER_FISHING, TARGET_DEST_CASTER_FRONT_LEAP, TARGET_DEST_CASTER_FRONT_LEFT, TARGET_DEST_CASTER_FRONT_RIGHT, TARGET_DEST_CASTER_RANDOM, TARGET_DEST_CASTER_SUMMON, TARGET_DEST_DB, TARGET_DEST_HOME, Object::ToPlayer(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1757{
1758 WorldObject* target = nullptr;
1759 bool checkIfValid = true;
1760
1761 switch (targetType.GetTarget())
1762 {
1763 case TARGET_UNIT_CASTER:
1764 target = m_caster;
1765 checkIfValid = false;
1766 break;
1767 case TARGET_UNIT_MASTER:
1768 target = m_caster->GetCharmerOrOwner();
1769 break;
1770 case TARGET_UNIT_PET:
1771 target = m_caster->GetGuardianPet();
1772 if (!target)
1773 target = m_caster->GetCharm();
1774 break;
1776 if (m_caster->IsSummon())
1777 target = m_caster->ToTempSummon()->GetSummonerUnit();
1778 break;
1780 target = m_caster->GetVehicleBase();
1781 break;
1791 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1792 break;
1793 default:
1794 break;
1795 }
1796
1797 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1798
1799 if (target && target->ToUnit())
1800 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1801}
@ TARGET_UNIT_PASSENGER_1
Definition: SharedDefines.h:1501
@ TARGET_UNIT_PASSENGER_6
Definition: SharedDefines.h:1506
@ TARGET_UNIT_VEHICLE
Definition: SharedDefines.h:1498
@ TARGET_UNIT_PASSENGER_2
Definition: SharedDefines.h:1502
@ TARGET_UNIT_PASSENGER_4
Definition: SharedDefines.h:1504
@ TARGET_UNIT_PASSENGER_7
Definition: SharedDefines.h:1507
@ TARGET_UNIT_MASTER
Definition: SharedDefines.h:1431
@ TARGET_UNIT_PASSENGER_5
Definition: SharedDefines.h:1505
@ TARGET_UNIT_PASSENGER_3
Definition: SharedDefines.h:1503
@ TARGET_UNIT_SUMMONER
Definition: SharedDefines.h:1496
@ TARGET_UNIT_PASSENGER_0
Definition: SharedDefines.h:1500
Unit * GetSummonerUnit() const
Definition: TemporarySummon.cpp:44
Unit * GetVehicleBase() const
Definition: Unit.cpp:18738
Unit * GetPassenger(int8 seatId) const
Definition: Vehicle.cpp:227

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), Unit::GetCharm(), Unit::GetCharmerOrOwner(), Unit::GetGuardianPet(), Vehicle::GetPassenger(), TempSummon::GetSummonerUnit(), SpellImplicitTargetInfo::GetTarget(), Unit::GetVehicleBase(), Unit::GetVehicleKit(), Object::IsCreature(), Unit::IsSummon(), Unit::IsVehicle(), m_caster, TARGET_UNIT_CASTER, TARGET_UNIT_MASTER, TARGET_UNIT_PASSENGER_0, TARGET_UNIT_PASSENGER_1, TARGET_UNIT_PASSENGER_2, TARGET_UNIT_PASSENGER_3, TARGET_UNIT_PASSENGER_4, TARGET_UNIT_PASSENGER_5, TARGET_UNIT_PASSENGER_6, TARGET_UNIT_PASSENGER_7, TARGET_UNIT_PET, TARGET_UNIT_SUMMONER, TARGET_UNIT_VEHICLE, Object::ToCreature(), Unit::ToTempSummon(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1826{
1827 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1828 if (Player* modOwner = m_caster->GetSpellModOwner())
1829 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1830
1831 if (maxTargets > 1)
1832 {
1833 // mark damage multipliers as used
1834 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1835 if (effMask & (1 << k))
1836 m_damageMultipliers[k] = 1.0f;
1837 m_applyMultiplierMask |= effMask;
1838
1839 std::list<WorldObject*> targets;
1840 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1841 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1842
1843 // Chain primary target is added earlier
1844 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1845
1846 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1847 if (Unit* unitTarget = (*itr)->ToUnit())
1848 AddUnitTarget(unitTarget, effMask, false);
1849 }
1850}
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition: SharedDefines.h:1449
@ SPELLMOD_JUMP_TARGETS
Definition: SpellDefines.h:93
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition: Spell.cpp:2195

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), Unit::GetSpellModOwner(), SpellImplicitTargetInfo::GetTarget(), SpellInfo::Id, m_applyMultiplierMask, m_caster, m_damageMultipliers, m_spellInfo, MAX_SPELL_EFFECTS, SearchChainTargets(), SPELLMOD_JUMP_TARGETS, TARGET_UNIT_TARGET_CHAINHEAL_ALLY, Object::ToUnit(), and unitTarget.

Referenced by SelectImplicitNearbyTargets(), and SelectImplicitTargetObjectTargets().

◆ SelectImplicitChannelTargets()

void Spell::SelectImplicitChannelTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1041{
1042 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1043 {
1044 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1045 return;
1046 }
1047
1048 switch (targetType.GetTarget())
1049 {
1051 {
1052 // Xinef: All channel selectors have needed data passed in m_targets structure
1054 if (target)
1055 {
1056 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1057 // unit target may be no longer avalible - teleported out of map for example
1058 if (target && target->ToUnit())
1059 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1060 }
1061 else
1062 {
1063 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1064 }
1065 break;
1066 }
1071 {
1072 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1073 if (target)
1074 m_targets.SetDst(*target);
1075 }
1077 {
1078 if (channeledSpell->m_targets.GetUnitTarget())
1079 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1080 }
1081 else //if (!m_targets.HasDst())
1082 {
1083 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1084 }
1085 break;
1087 if (GetOriginalCaster())
1089 break;
1090 default:
1091 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1092 break;
1093 }
1094}
@ TARGET_DEST_CHANNEL_TARGET
Definition: SharedDefines.h:1480
@ TARGET_UNIT_CHANNEL_TARGET
Definition: SharedDefines.h:1481
@ TARGET_DEST_CHANNEL_CASTER
Definition: SharedDefines.h:1510
WorldObject * GetObjectTargetChannel(Unit *caster) const
Definition: Spell.cpp:464
SpellDestination const * GetDstChannel() const
Definition: Spell.cpp:474
bool HasDstChannel() const
Definition: Spell.cpp:469

References AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), CURRENT_CHANNELED_SPELL, Unit::GetCurrentSpell(), SpellCastTargets::GetDstChannel(), SpellCastTargets::GetObjectTargetChannel(), GetOriginalCaster(), SpellImplicitTargetInfo::GetReferenceType(), SpellImplicitTargetInfo::GetTarget(), SpellCastTargets::HasDstChannel(), SpellInfo::Id, LOG_DEBUG, m_caster, m_originalCaster, m_spellInfo, m_targets, SpellCastTargets::SetDst(), TARGET_DEST_CHANNEL_CASTER, TARGET_DEST_CHANNEL_TARGET, TARGET_REFERENCE_TYPE_CASTER, TARGET_UNIT_CHANNEL_TARGET, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

void Spell::SelectImplicitConeTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1211{
1212 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1213 {
1214 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1215 return;
1216 }
1217 std::list<WorldObject*> targets;
1218 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1219 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1220 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1221 float coneAngle = M_PI / 2;
1222 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1223
1224 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1225 {
1226 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1227 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1228 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1229
1230 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1231
1232 if (!targets.empty())
1233 {
1234 // Other special target selection goes here
1235 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1236 {
1238 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
1239 if ((*j)->IsAffectedOnSpell(m_spellInfo))
1240 maxTargets += (*j)->GetAmount();
1241
1242 Acore::Containers::RandomResize(targets, maxTargets);
1243 }
1244
1245 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1246 {
1247 if (Unit* unit = (*itr)->ToUnit())
1248 {
1249 AddUnitTarget(unit, effMask, false);
1250 }
1251 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1252 {
1253 AddGOTarget(gObjTarget, effMask);
1254 }
1255 }
1256 }
1257 }
1258}
SpellTargetCheckTypes
Definition: SpellInfo.h:113
SpellTargetObjectTypes
Definition: SpellInfo.h:97

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, Unit::GetAuraEffectsByType(), SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), GetSearcherTypeMask(), m_caster, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, Acore::Containers::RandomResize(), SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1718{
1719 // set destination to caster if no dest provided
1720 // can only happen if previous destination target could not be set for some reason
1721 // (not found nearby target, or channel target for example
1722 // maybe we should abort the spell in such case?
1723 CheckDst();
1724
1726
1727 switch (targetType.GetTarget())
1728 {
1732 case TARGET_DEST_DEST:
1733 return;
1734 case TARGET_DEST_TRAJ:
1735 SelectImplicitTrajTargets(effIndex, targetType);
1736 return;
1737 default:
1738 {
1739 float angle = targetType.CalcDirectionAngle();
1740 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1741 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1742 dist *= float(rand_norm());
1743
1744 Position pos = dest._position;
1745 m_caster->MovePosition(pos, dist, angle);
1746
1747 dest.Relocate(pos);
1748 break;
1749 }
1750 }
1751
1752 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1753 m_targets.ModDst(dest);
1754}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition: SharedDefines.h:1432
@ TARGET_DEST_DEST_RANDOM
Definition: SharedDefines.h:1490
@ TARGET_DEST_DEST
Definition: SharedDefines.h:1491
@ TARGET_DEST_DYNOBJ_NONE
Definition: SharedDefines.h:1492
@ TARGET_DEST_DYNOBJ_ALLY
Definition: SharedDefines.h:1433
@ TARGET_DEST_TRAJ
Definition: SharedDefines.h:1493
void MovePosition(Position &pos, float dist, float angle, bool disableWarning=false)
Definition: Object.cpp:2776
void ModDst(Position const &pos)
Definition: Spell.cpp:436
SpellDestination const * GetDst() const
Definition: Spell.cpp:396

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePosition(), rand_norm(), SpellDestination::Relocate(), SelectImplicitTrajTargets(), TARGET_DEST_DEST, TARGET_DEST_DEST_RANDOM, TARGET_DEST_DYNOBJ_ALLY, TARGET_DEST_DYNOBJ_ENEMY, TARGET_DEST_DYNOBJ_NONE, and TARGET_DEST_TRAJ.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitNearbyTargets()

void Spell::SelectImplicitNearbyTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32  effMask 
)
1097{
1098 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1099 {
1100 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1101 return;
1102 }
1103
1104 float range = 0.0f;
1105 switch (targetType.GetCheckType())
1106 {
1107 case TARGET_CHECK_ENEMY:
1108 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1109 break;
1110 case TARGET_CHECK_ALLY:
1111 case TARGET_CHECK_PARTY:
1112 case TARGET_CHECK_RAID:
1114 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1115 break;
1116 case TARGET_CHECK_ENTRY:
1119 break;
1120 default:
1121 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1122 break;
1123 }
1124
1125 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1126
1127 // handle emergency case - try to use other provided targets if no conditions provided
1128 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1129 {
1130 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID {}, effect {} - selecting default targets", m_spellInfo->Id, effIndex);
1131 switch (targetType.GetObjectType())
1132 {
1135 {
1136 if (focusObject)
1137 AddGOTarget(focusObject, effMask);
1138 return;
1139 }
1140 break;
1143 {
1144 if (focusObject)
1146 return;
1147 }
1148 break;
1149 default:
1150 break;
1151 }
1152 }
1153
1154 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1155 if (!target)
1156 {
1157 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1158 return;
1159 }
1160
1161 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1162 if (!target)
1163 {
1164 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1165 return;
1166 }
1167
1168 switch (targetType.GetObjectType())
1169 {
1171 {
1172 if (Unit* unit = target->ToUnit())
1173 {
1174 AddUnitTarget(unit, effMask, true, false);
1175 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1176 // and if channeled spell has target 77, it requires unitTarget, set it here!
1177 // xinef: if we have NO unit target
1178 if (!m_targets.GetUnitTarget())
1179 {
1181 }
1182 }
1183 else
1184 {
1185 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected unit, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1186 return;
1187 }
1188 break;
1189 }
1191 if (GameObject* gobjTarget = target->ToGameObject())
1192 AddGOTarget(gobjTarget, effMask);
1193 else
1194 {
1195 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set object of wrong type, expected gameobject, got {}, effect {}", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask);
1196 return;
1197 }
1198 break;
1200 m_targets.SetDst(*target);
1201 break;
1202 default:
1203 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1204 break;
1205 }
1206
1207 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1208}
@ TARGET_CHECK_PARTY
Definition: SpellInfo.h:118
@ TARGET_CHECK_ENEMY
Definition: SpellInfo.h:116
@ TARGET_CHECK_DEFAULT
Definition: SpellInfo.h:114
@ TARGET_CHECK_RAID_CLASS
Definition: SpellInfo.h:120
@ TARGET_CHECK_ALLY
Definition: SpellInfo.h:117
@ TARGET_CHECK_RAID
Definition: SpellInfo.h:119
WorldObject * SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
Definition: Spell.cpp:2173
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition: Spell.cpp:1825

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellInfo::Effects, focusObject, SpellImplicitTargetInfo::GetCheckType(), SpellInfo::GetMaxRange(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetUnitTarget(), SpellInfo::Id, SpellInfo::IsPositive(), LOG_DEBUG, m_caster, m_spellInfo, m_targets, SpellInfo::RequiresSpellFocus, SearchNearbyTarget(), SelectImplicitChainTargets(), SpellCastTargets::SetDst(), SpellCastTargets::SetUnitTarget(), TARGET_CHECK_ALLY, TARGET_CHECK_DEFAULT, TARGET_CHECK_ENEMY, TARGET_CHECK_ENTRY, TARGET_CHECK_PARTY, TARGET_CHECK_RAID, TARGET_CHECK_RAID_CLASS, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetDestTargets()

void Spell::SelectImplicitTargetDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1681{
1683
1684 SpellDestination dest(*target);
1685
1686 switch (targetType.GetTarget())
1687 {
1690 break;
1691 default:
1692 {
1693 float angle = targetType.CalcDirectionAngle();
1694 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1695 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1696 {
1697 dist *= float(rand_norm());
1698 }
1699
1700 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1701 {
1703 }
1704
1705 Position pos = dest._position;
1706 target->MovePositionToFirstCollision(pos, dist, angle);
1707
1708 dest.Relocate(pos);
1709 break;
1710 }
1711 }
1712
1713 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1714 m_targets.SetDst(dest);
1715}
@ TARGET_DEST_TARGET_ANY
Definition: SharedDefines.h:1467
@ TARGET_DEST_TARGET_BACK
Definition: SharedDefines.h:1469
@ TARGET_DEST_TARGET_RANDOM
Definition: SharedDefines.h:1478
@ TARGET_DEST_TARGET_ENEMY
Definition: SharedDefines.h:1457
@ UNIT_FIELD_BOUNDINGRADIUS
Definition: UpdateFields.h:122

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), SpellInfo::Effects, Object::GetFloatValue(), SpellCastTargets::GetObjectTarget(), SpellImplicitTargetInfo::GetTarget(), m_spellInfo, m_targets, WorldObject::MovePositionToFirstCollision(), rand_norm(), SpellDestination::Relocate(), SpellCastTargets::SetDst(), TARGET_DEST_TARGET_ANY, TARGET_DEST_TARGET_BACK, TARGET_DEST_TARGET_ENEMY, TARGET_DEST_TARGET_RANDOM, and UNIT_FIELD_BOUNDINGRADIUS.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1804{
1805 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1806
1808
1809 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1810
1811 if (target)
1812 {
1813 if (Unit* unit = target->ToUnit())
1814 AddUnitTarget(unit, 1 << effIndex, true, false);
1815 else if (GameObject* gobj = target->ToGameObject())
1816 AddGOTarget(gobj, 1 << effIndex);
1817
1818 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1819 }
1820 // Script hook can remove object target and we would wrongly land here
1821 else if (Item* item = m_targets.GetItemTarget())
1822 AddItemTarget(item, 1 << effIndex);
1823}

References AddGOTarget(), AddItemTarget(), AddUnitTarget(), ASSERT, CallScriptObjectTargetSelectHandlers(), SpellCastTargets::GetItemTarget(), SpellCastTargets::GetObjectTarget(), m_targets, SelectImplicitChainTargets(), Object::ToGameObject(), and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTrajTargets()

void Spell::SelectImplicitTrajTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
: all calculation should be based on src instead of m_caster
1867{
1868 if (!m_targets.HasTraj())
1869 return;
1870
1871 float dist2d = m_targets.GetDist2d();
1872 if (!dist2d)
1873 return;
1874
1875 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
1876
1877 // xinef: supply correct target type, DEST_DEST and similar are ALWAYS undefined
1878 // xinef: correct target is stored in TRIGGERED SPELL, however as far as i noticed, all checks are ENTRY, ENEMY
1879 std::list<WorldObject*> targets;
1880 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo, TARGET_CHECK_ENEMY /*targetCheckType*/, m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1882 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
1883 if (targets.empty())
1884 return;
1885
1887
1888 float b = tangent(m_targets.GetElevation());
1889 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1890 if (a > -0.0001f)
1891 a = 0;
1892
1893 LOG_DEBUG("spells", "Spell::SelectTrajTargets: a {} b {}", a, b);
1894
1895 // Xinef: hack for distance, many trajectory spells have RangeEntry 1 (self)
1896 float bestDist = m_spellInfo->GetMaxRange(false) * 2;
1897 if (bestDist < 1.0f)
1898 bestDist = 300.0f;
1899
1900 std::list<WorldObject*>::const_iterator itr = targets.begin();
1901 for (; itr != targets.end(); ++itr)
1902 {
1903 if (Unit* unitTarget = (*itr)->ToUnit())
1904 if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
1905 continue;
1906
1907 const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
1909 const float objDist2d = std::fabs(m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr)));
1910 const float dz = std::fabs((*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ);
1911
1912 LOG_DEBUG("spells", "Spell::SelectTrajTargets: check {}, dist between {} {}, height between {} {}.",
1913 (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);
1914
1915 float dist = objDist2d - size;
1916 float height = dist * (a * dist + b);
1917
1918 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);
1919
1920 if (dist < bestDist && height < dz + size && height > dz - size)
1921 {
1922 bestDist = dist > 0 ? dist : 0;
1923 break;
1924 }
1925
1926#define CHECK_DIST {\
1927 LOG_DEBUG("spells", "Spell::SelectTrajTargets: dist {}, height {}.", dist, height);\
1928 if (dist > bestDist)\
1929 continue;\
1930 if (dist < objDist2d + size && dist > objDist2d - size)\
1931 {\
1932 bestDist = dist;\
1933 break;\
1934 }\
1935 }
1936
1937 // RP-GG only, search in straight line, as item have no trajectory
1938 if (m_CastItem)
1939 {
1940 if (dist < bestDist && std::fabs(dz) < 6.0f) // closes target, also check Z difference)
1941 {
1942 bestDist = dist;
1943 break;
1944 }
1945
1946 continue;
1947 }
1948
1949 if (!a)
1950 {
1951 // Xinef: everything remade
1952 dist = m_targets.GetSrcPos()->GetExactDist(*itr);
1953 height = m_targets.GetSrcPos()->GetExactDist2d(*itr) * b;
1954
1955 if (height < dz + size * (b + 1) && height > dz - size * (b + 1) && dist < bestDist)
1956 {
1957 bestDist = dist;
1958 break;
1959 }
1960
1961 continue;
1962 }
1963
1964 height = dz - size;
1965 float sqrt1 = b * b + 4 * a * height;
1966 if (sqrt1 > 0)
1967 {
1968 sqrt1 = std::sqrt(sqrt1);
1969 dist = (sqrt1 - b) / (2 * a);
1970 CHECK_DIST;
1971 }
1972
1973 height = dz + size;
1974 float sqrt2 = b * b + 4 * a * height;
1975 if (sqrt2 > 0)
1976 {
1977 sqrt2 = std::sqrt(sqrt2);
1978 dist = (sqrt2 - b) / (2 * a);
1979 CHECK_DIST;
1980
1981 dist = (-sqrt2 - b) / (2 * a);
1982 CHECK_DIST;
1983 }
1984
1985 if (sqrt1 > 0)
1986 {
1987 dist = (-sqrt1 - b) / (2 * a);
1988 CHECK_DIST;
1989 }
1990 }
1991
1993 {
1994 float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
1995 float y = m_targets.GetSrcPos()->m_positionY + std::sin(m_caster->GetOrientation()) * bestDist;
1996 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1997
1998 if (itr != targets.end())
1999 {
2000 float distSq = (*itr)->GetExactDistSq(x, y, z);
2001 float sizeSq = (*itr)->GetObjectSize();
2002 sizeSq *= sizeSq;
2003 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2004 if (distSq > sizeSq)
2005 {
2006 float factor = 1 - std::sqrt(sizeSq / distSq);
2007 x += factor * ((*itr)->GetPositionX() - x);
2008 y += factor * ((*itr)->GetPositionY() - y);
2009 z += factor * ((*itr)->GetPositionZ() - z);
2010
2011 distSq = (*itr)->GetExactDistSq(x, y, z);
2012 LOG_DEBUG("spells", "Spell::SelectTrajTargets: Initial {} {} {} {} {}", x, y, z, distSq, sizeSq);
2013 }
2014 }
2015
2016 Position trajDst;
2017 trajDst.Relocate(x, y, z, m_caster->GetOrientation());
2019 dest.Relocate(trajDst);
2020
2021 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2022 m_targets.ModDst(dest);
2023 }
2024}
float tangent(float x)
Definition: Spell.cpp:1852
#define CHECK_DIST
Definition: Object.h:696
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:1741
float GetElevation() const
Definition: Spell.h:170

References CallScriptDestinationTargetSelectHandlers(), CHECK_DIST, SpellInfo::Effects, SpellCastTargets::GetDist2d(), SpellCastTargets::GetDst(), SpellCastTargets::GetDstPos(), SpellCastTargets::GetElevation(), Position::GetExactDist(), Position::GetExactDist2d(), SpellInfo::GetMaxRange(), Position::GetOrientation(), Position::GetRelativeAngle(), SpellCastTargets::GetSrcPos(), GRID_MAP_TYPE_MASK_ALL, SpellCastTargets::HasTraj(), Unit::IsOnVehicle(), LOG_DEBUG, m_caster, m_CastItem, Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_spellInfo, m_targets, SpellCastTargets::ModDst(), Position::Relocate(), SpellDestination::Relocate(), tangent(), TARGET_CHECK_ENEMY, Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ SelectSpellTargets()

void Spell::SelectSpellTargets ( )
816{
817 // select targets for cast phase
819
820 uint32 processedAreaEffectsMask = 0;
821 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
822 {
823 // not call for empty effect.
824 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
825 if (!m_spellInfo->Effects[i].IsEffect())
826 continue;
827
828 // set expected type of implicit targets to be sent to client
829 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
830 if (implicitTargetMask & TARGET_FLAG_UNIT)
832 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
834
835 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
836 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
837
838 // Select targets of effect based on effect type
839 // those are used when no valid target could be added for spell effect based on spell target type
840 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
841 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
842 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
844
845 if (m_targets.HasDst())
847
849 {
850 // maybe do this for all spells?
851 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
852 {
854 finish(false);
855 return;
856 }
857
858 uint8 mask = (1 << i);
859 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
860 {
861 if (ihit->effectMask & mask)
862 {
864 break;
865 }
866 }
867 }
868 else if (m_auraScaleMask)
869 {
870 bool checkLvl = !m_UniqueTargetInfo.empty();
871 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
872 {
873 // remove targets which did not pass min level check
874 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
875 {
876 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
877 return true;
878 }
879
880 return false;
881 }), std::end(m_UniqueTargetInfo));
882
883 if (checkLvl && m_UniqueTargetInfo.empty())
884 {
886 finish(false);
887 }
888 }
889 }
890
891 if (uint64 dstDelay = CalculateDelayMomentForDst())
892 m_delayMoment = dstDelay;
893}
@ TARGET_FLAG_GAMEOBJECT
Definition: SpellInfo.h:57
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellInfo.h:60
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
Definition: SpellInfo.cpp:31
void SetTargetFlag(SpellCastTargetFlags flag)
Definition: Spell.h:122
void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 &processedEffectMask)
Definition: Spell.cpp:922
void SelectExplicitTargets()
Definition: Spell.cpp:782
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition: Spell.cpp:2604
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition: Spell.cpp:2026

References AddDestTarget(), CalculateDelayMomentForDst(), TargetInfo::effectMask, SpellInfo::Effects, finish(), focusObject, SpellCastTargets::GetDst(), GetTargetFlagMask(), SpellCastTargets::HasDst(), SpellInfo::IsChanneled(), m_auraScaleMask, m_channelTargetEffectMask, m_delayMoment, m_spellInfo, m_targets, m_UniqueGOTargetInfo, m_UniqueItemInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SendCastResult(), SpellCastTargets::SetTargetFlag(), SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_LOWLEVEL, TARGET_FLAG_GAMEOBJECT, TARGET_FLAG_GAMEOBJECT_ITEM, and TARGET_FLAG_UNIT.

Referenced by _cast(), CanAutoCast(), spell_dk_raise_dead::CheckCast(), and prepare().

◆ SendCastResult() [1/2]

void Spell::SendCastResult ( Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError = SPELL_CUSTOM_ERROR_NONE 
)
static
4671{
4672 if (result == SPELL_CAST_OK)
4673 return;
4674
4675 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4676 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4677
4678 caster->GetSession()->SendPacket(&data);
4679}
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition: Spell.cpp:4565

References Player::GetSession(), WorldSession::SendPacket(), SMSG_CAST_FAILED, SPELL_CAST_OK, and WriteCastResultInfo().

Referenced by _cast(), Unit::AttackerStateUpdate(), cancel(), Player::CastItemUseSpell(), spell_q12237_rescue_villager::CheckCast(), spell_q12237_drop_off_villager::CheckCast(), spell_dk_raise_dead::CheckReagents(), spell_putricide_mutation_init::CheckRequirement(), EffectApplyGlyph(), EffectDuel(), EffectOpenLock(), EffectTaunt(), SpellScript::FinishCast(), go_soulwell::go_soulwellAI::GossipHello(), WorldSession::HandleAcceptTradeOpcode(), spell_the_flag_of_ownership::HandleFinish(), WorldSession::HandlePetActionHelper(), spell_putricide_mutated_transformation::HandleSummon(), misc_commandscript::HandleUnstuckCommand(), icecrown_citadel_teleport::OnGossipSelect(), at_frozen_throne_teleport::OnTrigger(), item_petrov_cluster_bombs::OnUse(), item_only_for_flight::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4682{
4683 if (result == SPELL_CAST_OK)
4684 return;
4685
4686 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4687 return;
4688
4689 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4690 return;
4691
4692 // Xinef: override every possible result, except for gm fail result... breaks many things and goes unnoticed because of this and makes me rage when i find this out
4694 result = SPELL_FAILED_DONT_REPORT;
4695
4697}
@ SPELL_FAILED_BM_OR_INVISGOD
Definition: SharedDefines.h:1108
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition: SpellDefines.h:146
bool IsCharmed() const
Definition: Unit.h:1235

References Player::GetSession(), HasTriggeredCastFlag(), Unit::IsCharmed(), Object::IsPlayer(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::PlayerLoading(), SendCastResult(), SPELL_CAST_OK, SPELL_FAILED_BM_OR_INVISGOD, SPELL_FAILED_DONT_REPORT, Object::ToPlayer(), and TRIGGERED_DONT_REPORT_CAST_ERROR.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5208{
5209 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5210 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5211 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5212 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5213
5214 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5215 data << m_caster->GetPackGUID();
5216 data << uint32(m_spellInfo->Id);
5217 data << uint32(duration);
5218
5219 m_caster->SendMessageToSet(&data, true);
5220
5223
5224 m_timer = duration;
5225 if (channelTarget)
5227
5229}
@ MSG_CHANNEL_START
Definition: Opcodes.h:343

References WorldObject::FindMap(), Object::GetGUID(), SpellCastTargets::GetObjectTargetGUID(), Object::GetPackGUID(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, m_targets, m_timer, m_UniqueGOTargetInfo, m_UniqueTargetInfo, MSG_CHANNEL_START, Player::NeedSendSpectatorData(), SpellInfo::NeedsExplicitUnitTarget(), ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToPlayer(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5176{
5177 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5178 data << m_caster->GetPackGUID();
5179 data << uint8(m_cast_count);
5180 data << uint32(m_spellInfo->Id);
5181 data << uint8(result);
5182 m_caster->SendMessageToSet(&data, true);
5183
5184 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5185 data << m_caster->GetPackGUID();
5186 data << uint8(m_cast_count);
5187 data << uint32(m_spellInfo->Id);
5188 data << uint8(result);
5189 m_caster->SendMessageToSet(&data, true);
5190}
@ SMSG_SPELL_FAILURE
Definition: Opcodes.h:337
@ SMSG_SPELL_FAILED_OTHER
Definition: Opcodes.h:708

References Object::GetPackGUID(), SpellInfo::Id, WorldPacket::Initialize(), m_cast_count, m_caster, m_spellInfo, WorldObject::SendMessageToSet(), SMSG_SPELL_FAILED_OTHER, and SMSG_SPELL_FAILURE.

Referenced by _cast(), Unit::AttackerStateUpdate(), and cancel().

◆ SendLogExecute()

void Spell::SendLogExecute ( )
5075{
5076 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5077
5078 data << m_caster->GetPackGUID();
5079
5080 data << uint32(m_spellInfo->Id);
5081
5082 uint8 effCount = 0;
5083 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5084 {
5085 if (m_effectExecuteData[i])
5086 ++effCount;
5087 }
5088
5089 if (!effCount)
5090 return;
5091
5092 data << uint32(effCount);
5093 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5094 {
5095 if (!m_effectExecuteData[i])
5096 continue;
5097
5098 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5099
5100 data.append(*m_effectExecuteData[i]);
5101
5102 delete m_effectExecuteData[i];
5103 m_effectExecuteData[i] = nullptr;
5104 }
5105 m_caster->SendMessageToSet(&data, true);
5106}
@ SMSG_SPELLLOGEXECUTE
Definition: Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
2016{
2017 Player* player = m_caster->ToPlayer();
2018 if (!player)
2019 return;
2020
2021 if (gameObjTarget)
2022 {
2023 // Players shouldn't be able to loot gameobjects that are currently despawned
2024 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2025 {
2026 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2027 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2028 return;
2029 }
2030 // special case, already has GossipHello inside so return and avoid calling twice
2032 {
2034 return;
2035 }
2036
2037 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2038 return;
2039
2040 if (gameObjTarget->AI()->GossipHello(player, false))
2041 return;
2042
2043 switch (gameObjTarget->GetGoType())
2044 {
2046 gameObjTarget->UseDoorOrButton(0, false, player);
2047 return;
2049 gameObjTarget->UseDoorOrButton(0, false, player);
2050
2051 // Xinef: properly link possible traps
2052 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2053 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2054 return;
2058 return;
2059
2061 // triggering linked GO
2064 return;
2065
2067 // triggering linked GO
2068 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2070
2071 // Don't return, let loots been taken
2072 default:
2073 break;
2074 }
2075 }
2076
2077 // Send loot
2078 player->SendLoot(guid, loottype);
2079}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition: SharedDefines.h:1568
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition: SharedDefines.h:1562
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:54
bool isSpawned() const
Definition: GameObject.h:189
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition: GameObject.cpp:1385
uint32 gossipID
Definition: GameObjectData.h:72
uint32 linkedTrap
Definition: GameObjectData.h:59
struct GameObjectTemplate::@228::@232 questgiver
struct GameObjectTemplate::@228::@237 spellFocus
struct GameObjectTemplate::@228::@233 chest
uint32 linkedTrapId
Definition: GameObjectData.h:90
void SendPreparedGossip(WorldObject *source)
Definition: PlayerGossip.cpp:209
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition: PlayerGossip.cpp:32

References GameObject::AI(), GameObjectTemplate::button, GameObjectTemplate::chest, GAMEOBJECT_TYPE_BUTTON, GAMEOBJECT_TYPE_CHEST, GAMEOBJECT_TYPE_DOOR, GAMEOBJECT_TYPE_GOOBER, GAMEOBJECT_TYPE_QUESTGIVER, GAMEOBJECT_TYPE_SPELL_FOCUS, gameObjTarget, GameObject::GetGOInfo(), GameObject::GetGoType(), Object::GetGUID(), WorldObject::GetName(), GameObjectAI::GossipHello(), GameObjectTemplate::gossipID, Player::IsGameMaster(), GameObject::isSpawned(), GameObjectTemplate::linkedTrap, GameObjectTemplate::linkedTrapId, LOG_ERROR, m_caster, Player::PrepareGossipMenu(), GameObjectTemplate::questgiver, Player::SendLoot(), Player::SendPreparedGossip(), GameObjectTemplate::spellFocus, sScriptMgr, Object::ToPlayer(), ObjectGuid::ToString(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4700{
4701 if (result == SPELL_CAST_OK)
4702 return;
4703
4704 Unit* owner = m_caster->GetCharmerOrOwner();
4705 if (!owner)
4706 return;
4707
4708 Player* player = owner->ToPlayer();
4709 if (!player)
4710 return;
4711
4712 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4714
4715 player->GetSession()->SendPacket(&data);
4716}
@ SMSG_PET_CAST_FAILED
Definition: Opcodes.h:342

References Unit::GetCharmerOrOwner(), Player::GetSession(), m_cast_count, m_caster, m_customError, m_spellInfo, WorldSession::SendPacket(), SMSG_PET_CAST_FAILED, SPELL_CAST_OK, Object::ToPlayer(), and WriteCastResultInfo().

Referenced by WorldSession::HandlePetActionHelper(), and WorldSession::HandlePetCastSpellOpcode().

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player target)
5232{
5233 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5234 // for player resurrections the name is looked up by guid
5235 std::string const sentName(m_caster->IsPlayer()
5236 ? ""
5238
5239 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5240 data << m_caster->GetGUID();
5241 data << uint32(sentName.size() + 1);
5242
5243 data << sentName;
5244 data << uint8(0); // null terminator
5245
5246 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5247 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5249 data << uint32(0);
5250 target->GetSession()->SendPacket(&data);
5251}
@ SPELL_ATTR3_NO_RES_TIMER
Definition: SharedDefines.h:497
@ SMSG_RESURRECT_REQUEST
Definition: Opcodes.h:377
virtual std::string const & GetNameForLocaleIdx(LocaleConstant) const
Definition: Object.h:461
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:498

References Object::GetGUID(), WorldObject::GetNameForLocaleIdx(), Player::GetSession(), WorldSession::GetSessionDbLocaleIndex(), SpellInfo::HasAttribute(), Object::IsPlayer(), m_caster, m_spellInfo, WorldSession::SendPacket(), SMSG_RESURRECT_REQUEST, and SPELL_ATTR3_NO_RES_TIMER.

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4357{
4358 // xinef: properly add creature cooldowns
4359 if (!m_caster->IsPlayer())
4360 {
4362 {
4363 // xinef: this should be added here
4364 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4365
4366 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4369 {
4370 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4371 data << m_caster->GetGUID();
4373 data << uint32(m_spellInfo->Id);
4375 player->SendDirectMessage(&data);
4376 }
4377 }
4378 return;
4379 }
4380
4381 Player* _player = m_caster->ToPlayer();
4382
4383 // mana/health/etc potions, disabled by client (until combat out as declarate)
4385 {
4386 // need in some way provided data for Spell::finish SendCooldownEvent
4387 _player->SetLastPotionId(m_CastItem->GetEntry());
4388 return;
4389 }
4390
4391 // have infinity cooldown but set at aura apply
4392 // do not set cooldown for triggered spells (needed by reincarnation)
4397 return;
4398
4400}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition: Unit.h:617
@ SMSG_SPELL_COOLDOWN
Definition: Opcodes.h:338
void SetLastPotionId(uint32 item_id)
Definition: Player.h:1796
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition: Player.cpp:10917
uint32 RecoveryTime
Definition: SpellInfo.h:348
bool RequireCooldownInfo() const
Definition: SpellInfo.cpp:1182

References Player::AddSpellAndCategoryCooldowns(), Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), Object::GetEntry(), Object::GetGUID(), HasTriggeredCastFlag(), SpellInfo::Id, SpellInfo::IsCooldownStartedOnEvent(), SpellInfo::IsPassive(), Object::IsPlayer(), Item::IsPotion(), m_caster, m_CastItem, m_spellInfo, SpellInfo::RecoveryTime, SpellInfo::RequireCooldownInfo(), Player::SetLastPotionId(), SMSG_SPELL_COOLDOWN, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, Object::ToPlayer(), TRIGGERED_IGNORE_EFFECTS, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4799{
4800 // not send invisible spell casting
4801 if (!IsNeedSendToClient(true))
4802 return;
4803
4804 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4805
4806 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4807
4808 // triggered spells with spell visual != 0
4810 castFlags |= CAST_FLAG_PENDING;
4811
4813 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4814
4815 // should only be sent to self, but the current messaging doesn't make that possible
4816 if (m_caster->IsPlayer() || m_caster->IsPet())
4817 {
4818 switch (m_spellInfo->PowerType)
4819 {
4820 case POWER_HEALTH:
4821 break;
4822 case POWER_RUNE:
4823 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4824 break;
4825 default:
4826 if (m_powerCost != 0)
4827 {
4828 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4829 }
4830 break;
4831 }
4832 }
4833
4834 if ((m_caster->IsPlayer())
4838 {
4839 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4840 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4841 }
4842
4844 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4845
4846 if (m_targets.HasTraj())
4847 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4848
4850 castFlags |= CAST_FLAG_NO_GCD;
4851
4852 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4853 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4854 {
4855 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4856 {
4857 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4858 {
4859 realCasterGUID = casterGameobject->GetPackGUID();
4860 }
4861 }
4862 }
4863
4864 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4865
4866 if (m_CastItem)
4867 data << m_CastItem->GetPackGUID();
4868 else
4869 data << realCasterGUID;
4870
4871 data << realCasterGUID;
4872 data << uint8(m_cast_count); // pending spell cast?
4873 data << uint32(m_spellInfo->Id); // spellId
4874 data << uint32(castFlags); // cast flags
4875 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4876
4877 WriteSpellGoTargets(&data);
4878
4879 m_targets.Write(data);
4880
4881 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4883
4884 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4885 {
4886 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4887 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4888 if (Player* player = m_caster->ToPlayer())
4889 {
4890 uint8 runeMaskInitial = m_runesState;
4891 uint8 runeMaskAfterCast = player->GetRunesState();
4892 data << uint8(runeMaskInitial); // runes state before
4893 data << uint8(runeMaskAfterCast); // runes state after
4894 for (uint8 i = 0; i < MAX_RUNES; ++i)
4895 {
4896 uint8 mask = (1 << i);
4897 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4898 {
4899 // float casts ensure the division is performed on floats as we need float result
4900 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4901 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4902 }
4903 }
4904 }
4905 }
4906 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4907 {
4908 data << m_targets.GetElevation();
4910 }
4911
4912 if (castFlags & CAST_FLAG_PROJECTILE)
4913 WriteAmmoToPacket(&data);
4914
4915 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4916 {
4917 data << uint32(0);
4918 data << uint32(0);
4919 }
4920
4922 {
4923 data << uint8(0);
4924 }
4925
4926 m_caster->SendMessageToSet(&data, true);
4927}
@ SPELL_EFFECT_ACTIVATE_RUNE
Definition: SharedDefines.h:924
@ SPELL_ATTR0_USES_RANGED_SLOT
Definition: SharedDefines.h:383
@ SPELL_ATTR0_CU_NEEDS_AMMO_DATA
Definition: SpellInfo.h:195
@ CAST_FLAG_VISUAL_CHAIN
Definition: Spell.h:65
@ CAST_FLAG_ADJUST_MISSILE
Definition: Spell.h:63
@ CAST_FLAG_UNKNOWN_9
Definition: Spell.h:54
@ CAST_FLAG_NO_GCD
Definition: Spell.h:64
@ CAST_FLAG_PROJECTILE
Definition: Spell.h:51
@ CAST_FLAG_POWER_LEFT_SELF
Definition: Spell.h:57
@ CAST_FLAG_RUNE_LIST
Definition: Spell.h:67
@ CAST_FLAG_PENDING
Definition: Spell.h:46
@ SMSG_SPELL_GO
Definition: Opcodes.h:336
Definition: ObjectGuid.h:263
void Write(ByteBuffer &data)
Definition: Spell.cpp:179
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition: Spell.cpp:5014
void WriteAmmoToPacket(WorldPacket *data)
Definition: Spell.cpp:4929
bool IsNeedSendToClient(bool go) const
Definition: Spell.cpp:8092
SpellCastTimesEntry const * CastTimeEntry
Definition: SpellInfo.h:347
int32 CastTime
Definition: DBCStructure.h:1759

References CAST_FLAG_ADJUST_MISSILE, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_RUNE_LIST, CAST_FLAG_UNKNOWN_9, CAST_FLAG_VISUAL_CHAIN, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, SpellCastTargets::GetElevation(), GameTime::GetGameTimeMS(), Object::GetPackGUID(), Unit::GetPower(), SpellCastTargets::GetTargetMask(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), Unit::IsClass(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_delayMoment, m_delayTrajectory, m_powerCost, m_runesState, m_spellInfo, m_targets, m_triggeredByAuraSpell, MAX_RUNES, POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, WorldObject::SendMessageToSet(), SMSG_SPELL_GO, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_EFFECT_ACTIVATE_RUNE, SpellInfo::StartRecoveryTime, TARGET_FLAG_DEST_LOCATION, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4719{
4720 if (!IsNeedSendToClient(false))
4721 return;
4722
4723 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4724
4725 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4726
4728 castFlags |= CAST_FLAG_PENDING;
4729
4731 castFlags |= CAST_FLAG_PROJECTILE;
4732
4733 if (m_caster->IsPlayer() || m_caster->IsPet())
4734 {
4735 switch (m_spellInfo->PowerType)
4736 {
4737 case POWER_HEALTH:
4738 break;
4739 case POWER_RUNE:
4740 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4741 break;
4742 default:
4743 if (m_powerCost != 0)
4744 {
4745 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4746 }
4747 break;
4748 }
4749 }
4750
4752 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4753
4754 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4755 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4756 {
4757 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4758 {
4759 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4760 {
4761 realCasterGUID = casterGameobject->GetPackGUID();
4762 }
4763 }
4764 }
4765
4766 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4767 if (m_CastItem)
4768 data << m_CastItem->GetPackGUID();
4769 else
4770 data << realCasterGUID;
4771
4772 data << realCasterGUID;
4773 data << uint8(m_cast_count); // pending spell cast?
4774 data << uint32(m_spellInfo->Id); // spellId
4775 data << uint32(castFlags); // cast flags
4776 data << int32(m_timer); // delay?
4777
4778 m_targets.Write(data);
4779
4780 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4782
4783 if (castFlags & CAST_FLAG_PROJECTILE)
4784 WriteAmmoToPacket(&data);
4785
4786 if (castFlags & CAST_FLAG_UNKNOWN_23)
4787 {
4788 data << uint32(0);
4789 data << uint32(0);
4790 }
4791
4792 m_caster->SendMessageToSet(&data, true);
4793
4796}
@ CAST_FLAG_UNKNOWN_23
Definition: Spell.h:68
@ CAST_FLAG_HAS_TRAJECTORY
Definition: Spell.h:47
@ SMSG_SPELL_START
Definition: Opcodes.h:335

References CAST_FLAG_HAS_TRAJECTORY, CAST_FLAG_NO_GCD, CAST_FLAG_PENDING, CAST_FLAG_POWER_LEFT_SELF, CAST_FLAG_PROJECTILE, CAST_FLAG_UNKNOWN_23, SpellCastTimesEntry::CastTime, SpellInfo::CastTimeEntry, WorldObject::FindMap(), Object::GetGUID(), Object::GetPackGUID(), Unit::GetPower(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsAutoRepeatRangedSpell(), SpellInfo::IsChanneled(), IsNeedSendToClient(), Unit::IsPet(), Object::IsPlayer(), IsTriggered(), m_cast_count, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_timer, m_triggeredByAuraSpell, Player::NeedSendSpectatorData(), POWER_HEALTH, POWER_RUNE, SpellInfo::PowerType, SpellInfo::RuneCostID, ArenaSpectator::SendCommand_Spell(), WorldObject::SendMessageToSet(), SMSG_SPELL_START, SPELL_ATTR0_CU_NEEDS_AMMO_DATA, SPELL_ATTR0_USES_RANGED_SLOT, Object::ToPlayer(), Unit::ToTempSummon(), WORLD_TRIGGER, SpellCastTargets::Write(), and WriteAmmoToPacket().

Referenced by prepare().

◆ SetAutoRepeat()

void Spell::SetAutoRepeat ( bool  rep)
inline
551{ m_autoRepeat = rep; }

References m_autoRepeat.

◆ SetDelayStart()

void Spell::SetDelayStart ( uint64  m_time)
inline
565{ m_delayStart = m_time; }

References m_delayStart.

Referenced by _cast(), and SpellEvent::Execute().

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
563{m_executedCurrently = yes;}

References m_executedCurrently.

Referenced by _cast(), and Unit::AttackerStateUpdate().

◆ SetReferencedFromCurrent()

void Spell::SetReferencedFromCurrent ( bool  yes)
inline

◆ SetSpellValue()

void Spell::SetSpellValue ( SpellValueMod  mod,
int32  value 
)
8434{
8435 switch (mod)
8436 {
8438 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8439 break;
8441 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8442 break;
8444 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8445 break;
8447 m_spellValue->RadiusMod = (float)value / 10000;
8448 break;
8451 break;
8454 break;
8456 m_spellValue->AuraDuration = value;
8457 break;
8459 m_spellValue->ForcedCritResult = (bool)value;
8460 break;
8461 }
8462}
@ SPELLVALUE_AURA_STACK
Definition: SpellDefines.h:118
@ SPELLVALUE_AURA_DURATION
Definition: SpellDefines.h:119
@ SPELLVALUE_RADIUS_MOD
Definition: SpellDefines.h:116
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:117
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition: SpellDefines.h:120
bool ForcedCritResult
Definition: Spell.h:220

References SpellValue::AuraDuration, SpellValue::AuraStackAmount, EFFECT_0, EFFECT_1, EFFECT_2, SpellValue::EffectBasePoints, SpellInfo::Effects, SpellValue::ForcedCritResult, m_spellInfo, m_spellValue, SpellValue::MaxAffectedTargets, SpellValue::RadiusMod, SPELLVALUE_AURA_DURATION, SPELLVALUE_AURA_STACK, SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, SPELLVALUE_BASE_POINT2, SPELLVALUE_FORCED_CRIT_RESULT, SPELLVALUE_MAX_TARGETS, and SPELLVALUE_RADIUS_MOD.

Referenced by Player::CastItemUseSpell(), Unit::CastSpell(), and spell_gen_mod_radius_by_caster_scale::PrepareSpellScript().

◆ setState()

void Spell::setState ( uint32  state)
inline
485{ m_spellState = state; }

References m_spellState.

◆ SummonGuardian()

void Spell::SummonGuardian ( uint32  i,
uint32  entry,
SummonPropertiesEntry const *  properties,
uint32  numSummons,
bool  personalSpawn 
)
protected
5957{
5958 Unit* caster = m_originalCaster;
5959 if (!caster)
5960 return;
5961
5962 if (caster->IsTotem())
5963 caster = caster->ToTotem()->GetOwner();
5964
5965 // in another case summon new
5966 uint8 summonLevel = caster->GetLevel();
5967
5968 // level of pet summoned using engineering item based at engineering skill level
5969 if (m_CastItem && caster->IsPlayer())
5970 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5971 {
5972 // xinef: few special cases
5973 if (proto->RequiredSkill == SKILL_ENGINEERING)
5974 {
5975 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
5976 summonLevel = skill202 / 5;
5977 }
5978
5979 switch (m_spellInfo->Id)
5980 {
5981 // Dragon's Call
5982 case 13049:
5983 summonLevel = 55;
5984 break;
5985
5986 // Cleansed Timberling Heart: Summon Timberling
5987 case 5666:
5988 summonLevel = 7;
5989 break;
5990
5991 // Glowing Cat Figurine: Summon Ghost Saber
5992 case 6084:
5993 // minLevel 19, maxLevel 20
5994 summonLevel = 20;
5995 break;
5996
5997 // Spiked Collar: Summon Felhunter
5998 case 8176:
5999 summonLevel = 30;
6000 break;
6001
6002 // Dog Whistle: Summon Tracking Hound
6003 case 9515:
6004 summonLevel = 30;
6005 break;
6006
6007 // Barov Peasant Caller: Death by Peasant
6008 case 18307:
6009 case 18308:
6010 summonLevel = 60;
6011 break;
6012
6013 // Thornling Seed: Plant Thornling
6014 case 22792:
6015 summonLevel = 60;
6016 break;
6017
6018 // Cannonball Runner: Summon Crimson Cannon
6019 case 6251:
6020 summonLevel = 61;
6021 break;
6022 }
6023 }
6024
6025 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6026
6027 float radius = 5.0f;
6028 int32 duration = m_spellInfo->GetDuration();
6029
6030 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6031 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6032
6033 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6034 Map* map = caster->GetMap();
6035 TempSummon* summon = nullptr;
6036
6037 uint32 currMinionsCount = m_caster->m_Controlled.size();
6038 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6039
6040 for (uint32 count = 0; count < numGuardians; ++count)
6041 {
6042 Position pos;
6043
6044 // xinef: do not use precalculated position for effect summon pet in this function
6045 // it means it was cast by NPC and should have its position overridden unless the
6046 // target position is specified in the DB AND the effect has no or zero radius
6047 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6048 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6049 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6050 {
6051 pos = *destTarget;
6052 }
6053 else
6054 {
6055 // randomize position
6056 pos = m_caster->GetRandomPoint(*destTarget, radius);
6057 }
6058
6059 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6060 if (!summon)
6061 return;
6062
6063 // xinef: set calculated level
6064 summon->SetLevel(summonLevel);
6065
6066 // if summonLevel changed, set stats for calculated level
6067 if (summonLevel != caster->GetLevel())
6068 {
6069 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6070 }
6071
6072 // xinef: if we have more than one guardian, change follow angle
6073 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6074 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6075 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6076 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6077
6078 // xinef: move this here, some auras are added in initstatsforlevel!
6079 if (!summon->IsInCombat() && !summon->IsTrigger())
6080 {
6081 // summon->AI()->EnterEvadeMode();
6082 summon->GetMotionMaster()->Clear(false);
6084 }
6085
6086 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6087 summon->SetFaction(caster->GetFaction());
6088
6090 }
6091}
@ SKILL_ENGINEERING
Definition: SharedDefines.h:2923
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:235
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: IWorld.h:285
bool IsTrigger() const
Definition: Creature.h:75
Definition: TemporarySummon.h:76
Unit * GetOwner() const
Definition: TemporarySummon.cpp:385
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition: Unit.cpp:15455

References SummonPropertiesEntry::Category, MotionMaster::Clear(), CONFIG_MAX_PLAYER_LEVEL, CONFIG_WORLD_BOSS_LEVEL_DIFF, destTarget, ExecuteLogEffectSummonObject(), Position::GetAbsoluteAngle(), SpellInfo::GetDuration(), Unit::GetFaction(), Unit::GetFollowAngle(), Unit::GetLevel(), WorldObject::GetMap(), Unit::GetMotionMaster(), Minion::GetOwner(), Position::GetPositionX(), Position::GetPositionY(), WorldObject::GetRandomPoint(), Player::GetSkillValue(), GetSpellInfo(), Unit::GetSpellModOwner(), Item::GetTemplate(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Object::IsPlayer(), Unit::IsTotem(), Creature::IsTrigger(), m_caster, m_CastItem, Unit::m_Controlled, m_originalCaster, m_spellInfo, MOTION_SLOT_ACTIVE, MotionMaster::MoveFollow(), PET_FOLLOW_DIST, Unit::SetFaction(), Unit::SetLevel(), SKILL_ENGINEERING, SPELL_EFFECT_SUMMON_PET, SPELLMOD_DURATION, SUMMON_CATEGORY_ALLY, Map::SummonCreature(), sWorld, TARGET_DEST_DB, Object::ToPlayer(), Unit::ToTotem(), and UNIT_MASK_MINION.

Referenced by EffectSummonPet(), and EffectSummonType().

◆ TakeAmmo()

void Spell::TakeAmmo ( )
5381{
5383 {
5385
5386 // wands don't have ammo
5387 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5388 return;
5389
5390 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5391 {
5392 if (pItem->GetMaxStackCount() == 1)
5393 {
5394 // decrease durability for non-stackable throw weapon
5396 }
5397 else
5398 {
5399 // decrease items amount for stackable throw weapon
5400 uint32 count = 1;
5401 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5402 }
5403 }
5405 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5406 }
5407}
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:692
@ INVTYPE_THROWN
Definition: ItemTemplate.h:281
uint32 GetMaxStackCount() const
Definition: Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition: Player.cpp:4812

References Player::DestroyItemCount(), Player::DurabilityPointLossForEquipSlot(), EQUIPMENT_SLOT_RANGED, Item::GetMaxStackCount(), Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), ItemTemplate::InventoryType, INVTYPE_THROWN, Item::IsBroken(), Object::IsPlayer(), ITEM_SUBCLASS_WEAPON_WAND, m_attackType, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, ItemTemplate::SubClass, and Object::ToPlayer().

Referenced by handle_immediate(), and HandleLaunchPhase().

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5254{
5255 if (!m_CastItem || !m_caster->IsPlayer())
5256 return;
5257
5258 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5260 return;
5261
5262 ItemTemplate const* proto = m_CastItem->GetTemplate();
5263
5264 if (!proto)
5265 {
5266 // This code is to avoid a crash
5267 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5268 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5269 return;
5270 }
5271
5272 bool expendable = false;
5273 bool withoutCharges = false;
5274
5275 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5276 {
5277 if (proto->Spells[i].SpellId)
5278 {
5279 // item has limited charges
5280 if (proto->Spells[i].SpellCharges)
5281 {
5282 if (proto->Spells[i].SpellCharges < 0)
5283 expendable = true;
5284
5285 int32 charges = m_CastItem->GetSpellCharges(i);
5286
5287 // item has charges left
5288 if (charges)
5289 {
5290 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5291 if (proto->Stackable == 1)
5292 m_CastItem->SetSpellCharges(i, charges);
5294 }
5295
5296 // all charges used
5297 withoutCharges = (charges == 0);
5298 }
5299 }
5300 }
5301
5302 if (expendable && withoutCharges)
5303 {
5304 uint32 count = 1;
5305 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5306
5307 // prevent crash at access to deleted m_targets.GetItemTarget
5309 m_targets.SetItemTarget(nullptr);
5310
5311 m_CastItem = nullptr;
5313 }
5314}
void SetSpellCharges(uint8 index, int32 value)
Definition: Item.h:318
int32 Stackable
Definition: ItemTemplate.h:645

References ObjectGuid::Clear(), Player::DestroyItemCount(), Object::GetGUID(), SpellCastTargets::GetItemTarget(), Item::GetSpellCharges(), Item::GetTemplate(), HasTriggeredCastFlag(), Object::IsPlayer(), ITEM_CHANGED, LOG_ERROR, m_caster, m_CastItem, m_castItemGUID, m_targets, MAX_ITEM_PROTO_SPELLS, SpellCastTargets::SetItemTarget(), Item::SetSpellCharges(), Item::SetState(), _Spell::SpellCharges, _Spell::SpellId, ItemTemplate::Spells, ItemTemplate::Stackable, Object::ToPlayer(), ObjectGuid::ToString(), and TRIGGERED_IGNORE_CAST_ITEM.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5317{
5319 return;
5320
5321 //Don't take power if the spell is cast while .cheat power is enabled.
5322 if (m_caster->IsPlayer())
5324 return;
5325
5327 bool hit = true;
5328 if (m_caster->IsPlayer())
5329 {
5331 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5332 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5333 if (ihit->targetGUID == targetGUID)
5334 {
5335 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5336 {
5337 hit = false;
5338 //lower spell cost on fail (by talent aura)
5339 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5340 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5341 }
5342 break;
5343 }
5344 }
5345
5346 if (PowerType == POWER_RUNE)
5347 {
5348 TakeRunePower(hit);
5349 return;
5350 }
5351
5352 if (!m_powerCost)
5353 return;
5354
5355 // health as power used
5356 if (PowerType == POWER_HEALTH)
5357 {
5359 return;
5360 }
5361
5362 if (PowerType >= MAX_POWERS)
5363 {
5364 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5365 return;
5366 }
5367
5368 if (hit)
5370 else
5372
5373 // Set the five second timer
5374 if (PowerType == POWER_MANA && m_powerCost > 0)
5375 {
5377 }
5378}
@ SPELL_MISS_ABSORB
Definition: SharedDefines.h:1529
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition: SpellDefines.h:106
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:14086
void SetLastManaUse(uint32 spellCastTime)
Definition: Unit.h:1073
void TakeRunePower(bool didHit)
Definition: Spell.cpp:5463

References CHEAT_POWER, Player::GetCommandStatus(), GameTime::GetGameTimeMS(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTargetGUID(), SpellInfo::Id, irand(), Object::IsPlayer(), LOG_ERROR, m_caster, m_CastItem, m_powerCost, m_spellInfo, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_POWERS, Unit::ModifyHealth(), Unit::ModifyPower(), POWER_ENERGY, POWER_HEALTH, POWER_MANA, POWER_RAGE, POWER_RUNE, POWER_RUNIC_POWER, SpellInfo::PowerType, Unit::SetLastManaUse(), SPELL_MISS_ABSORB, SPELL_MISS_BLOCK, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, TakeRunePower(), and Object::ToPlayer().

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5533{
5534 if (!m_caster->IsPlayer())
5535 return;
5536
5537 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5538
5539 // do not take reagents for these item casts
5540 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5541 return;
5542
5543 Player* p_caster = m_caster->ToPlayer();
5544 if (p_caster->CanNoReagentCast(m_spellInfo))
5545 return;
5546
5547 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5548 {
5549 if (m_spellInfo->Reagent[x] <= 0)
5550 continue;
5551
5552 uint32 itemid = m_spellInfo->Reagent[x];
5553 uint32 itemcount = m_spellInfo->ReagentCount[x];
5554
5555 // if CastItem is also spell reagent
5556 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5557 {
5558 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5559 {
5560 // CastItem will be used up and does not count as reagent
5561 int32 charges = m_CastItem->GetSpellCharges(s);
5562 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5563 {
5564 ++itemcount;
5565 break;
5566 }
5567 }
5568
5569 m_CastItem = nullptr;
5571 }
5572
5573 // if GetItemTarget is also spell reagent
5574 if (m_targets.GetItemTargetEntry() == itemid)
5575 m_targets.SetItemTarget(nullptr);
5576
5577 p_caster->DestroyItemCount(itemid, itemcount, true);
5578 }
5579}
uint32 ItemId
Definition: ItemTemplate.h:620

References Player::CanNoReagentCast(), ObjectGuid::Clear(), Player::DestroyItemCount(), SpellCastTargets::GetItemTargetEntry(), Item::GetSpellCharges(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_NO_REAGENT_COST, ItemTemplate::ItemId, m_caster, m_CastItem, m_castItemGUID, m_spellInfo, m_targets, MAX_ITEM_PROTO_SPELLS, MAX_SPELL_REAGENTS, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellCastTargets::SetItemTarget(), _Spell::SpellCharges, ItemTemplate::Spells, and Object::ToPlayer().

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5464{
5466 return;
5467
5468 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5469 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5470 return;
5471
5472 Player* player = m_caster->ToPlayer();
5473 m_runesState = player->GetRunesState(); // store previous state
5474
5475 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5476
5477 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5478 {
5479 runeCost[i] = runeCostData->RuneCost[i];
5480 if (Player* modOwner = m_caster->GetSpellModOwner())
5481 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5482 }
5483
5484 runeCost[RUNE_DEATH] = 0; // calculated later
5485
5486 for (uint32 i = 0; i < MAX_RUNES; ++i)
5487 {
5488 RuneType rune = player->GetCurrentRune(i);
5489 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5490 {
5491 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5492 player->SetLastUsedRune(rune);
5493 runeCost[rune]--;
5494 }
5495 }
5496
5497 // Xinef: firstly consume death runes of base type
5498 // Xinef: in second loop consume all available
5499 for (uint8 loop = 0; loop < 2; ++loop)
5500 {
5501 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5502 if (runeCost[RUNE_DEATH] > 0)
5503 {
5504 for (uint8 i = 0; i < MAX_RUNES; ++i)
5505 {
5506 RuneType rune = player->GetCurrentRune(i);
5507 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5508 {
5509 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5510 player->SetLastUsedRune(rune);
5511 runeCost[rune]--;
5512 if (!loop)
5513 runeCost[player->GetBaseRune(i)]--;
5514
5515 // keep Death Rune type if missed
5516 if (didHit)
5517 player->RestoreBaseRune(i);
5518
5519 if (runeCost[RUNE_DEATH] == 0)
5520 break;
5521 }
5522 }
5523 }
5524 }
5525
5526 // you can gain some runic power when use runes
5527 if (didHit)
5528 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5529 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5530}
@ RATE_POWER_RUNICPOWER_INCOME
Definition: IWorld.h:432
@ RUNE_UNHOLY
Definition: Player.h:410
@ RUNE_BLOOD
Definition: Player.h:409
@ RUNE_MISS_COOLDOWN
Definition: Player.h:404
void SetLastUsedRune(RuneType type)
Definition: Player.h:2496
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition: Player.cpp:13379
void RestoreBaseRune(uint8 index)
Definition: Player.cpp:13408
bool NoRunicPowerGain() const
Definition: DBCStructure.h:1810
uint32 runePowerGain
Definition: DBCStructure.h:1807

References CLASS_CONTEXT_ABILITY, CLASS_DEATH_KNIGHT, Player::GetBaseRune(), Player::GetCurrentRune(), Player::GetRuneBaseCooldown(), Player::GetRuneCooldown(), Player::GetRunesState(), Unit::GetSpellModOwner(), SpellInfo::Id, Unit::IsClass(), Object::IsPlayer(), m_caster, m_runesState, m_spellInfo, MAX_RUNES, Unit::ModifyPower(), SpellRuneCostEntry::NoRuneCost(), SpellRuneCostEntry::NoRunicPowerGain(), NUM_RUNE_TYPES, POWER_RUNIC_POWER, RATE_POWER_RUNICPOWER_INCOME, Player::RestoreBaseRune(), RUNE_BLOOD, RUNE_DEATH, RUNE_FROST, RUNE_MISS_COOLDOWN, RUNE_UNHOLY, SpellRuneCostEntry::RuneCost, SpellInfo::RuneCostID, SpellRuneCostEntry::runePowerGain, Player::SetLastUsedRune(), Player::SetRuneCooldown(), SPELLMOD_COST, sSpellRuneCostStore, sWorld, and Object::ToPlayer().

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
8842{
8844 if (!gcd)
8845 {
8846 // Xinef: fix for charmed pet spells with no cooldown info
8848 gcd = MIN_GCD;
8849 else
8850 return;
8851 }
8852
8853 if (m_caster->IsPlayer())
8855 return;
8856
8857 // Global cooldown can't leave range 1..1.5 secs
8858 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8859 // but as tests show are not affected by any spell mods.
8861 {
8862 // gcd modifier auras are applied only to own spells and only players have such mods
8863 if (m_caster->IsPlayer())
8865
8866 // Apply haste rating
8869 {
8870 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8871 }
8872
8873 if (gcd < MIN_GCD)
8874 gcd = MIN_GCD;
8875 else if (gcd > MAX_GCD)
8876 gcd = MAX_GCD;
8877 }
8878
8879 // Only players or controlled units have global cooldown
8880 if (m_caster->GetCharmInfo())
8882 else if (m_caster->IsPlayer())
8884}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition: SpellDefines.h:97
@ MIN_GCD
Definition: Spell.cpp:8826
@ MAX_GCD
Definition: Spell.cpp:8827
void AddGlobalCooldown(SpellInfo const *spellInfo, uint32 gcd)
Definition: CharmInfo.cpp:403

References GlobalCooldownMgr::AddGlobalCooldown(), Player::ApplySpellMod(), SpellInfo::CategoryRecoveryTime, CHEAT_COOLDOWN, SpellInfo::DmgClass, Unit::GetCharmInfo(), Player::GetCommandStatus(), Object::GetFloatValue(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), SpellInfo::HasAttribute(), SpellInfo::Id, Object::IsPlayer(), m_caster, m_spellInfo, MAX_GCD, MIN_GCD, SpellInfo::RecoveryTime, SPELL_ATTR0_IS_ABILITY, SPELL_ATTR0_USES_RANGED_SLOT, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELLMOD_GLOBAL_COOLDOWN, SpellInfo::StartRecoveryCategory, SpellInfo::StartRecoveryTime, Object::ToPlayer(), and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4403{
4404 // update pointers based at it's GUIDs
4405 if (!UpdatePointers())
4406 {
4407 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4408 cancel();
4409 return;
4410 }
4411
4413 {
4414 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4415 cancel();
4416 return;
4417 }
4418
4419 // check if the player caster has moved before the spell finished
4420 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4421 if ((m_caster->IsPlayer() && m_timer != 0) &&
4424 {
4425 // don't cancel for melee, autorepeat, triggered and instant spells
4427 cancel(true);
4428 }
4429
4430 switch (m_spellState)
4431 {
4433 {
4434 if (m_timer > 0)
4435 {
4436 if (difftime >= (uint32)m_timer)
4437 m_timer = 0;
4438 else
4439 m_timer -= difftime;
4440 }
4441
4442 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4443 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4444 cast(!m_casttime);
4445 break;
4446 }
4448 {
4449 if (m_timer)
4450 {
4451 if (m_timer > 0)
4452 {
4453 if (difftime >= (uint32)m_timer)
4454 m_timer = 0;
4455 else
4456 m_timer -= difftime;
4457 }
4458 }
4459
4460 if (m_timer == 0)
4461 {
4463
4464 finish();
4465 }
4466 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4467 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4468 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4469 // Xinef: so the aura can be removed in different updates for all units
4470 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4471 {
4472 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4474 finish();
4475 }
4476 break;
4477 }
4478 default:
4479 break;
4480 }
4481}
bool UpdateChanneledTargetList()
Definition: Spell.cpp:3388

References cancel(), cast(), SpellInfo::Effects, finish(), SpellCastTargets::GetUnitTarget(), SpellCastTargets::GetUnitTargetGUID(), Unit::HasUnitMovementFlag(), SpellInfo::Id, SpellInfo::InterruptFlags, IsAutoRepeat(), Unit::isMoving(), IsNextMeleeSwingSpell(), Object::IsPlayer(), IsTriggered(), LOG_DEBUG, m_caster, m_casttime, m_spellInfo, m_spellState, m_targets, m_timer, MOVEMENTFLAG_FALLING_FAR, SendChannelUpdate(), SPELL_EFFECT_STUCK, SPELL_INTERRUPT_FLAG_MOVEMENT, SPELL_STATE_CASTING, SPELL_STATE_PREPARING, UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3389{
3390 // Not need check return true
3392 return true;
3393
3394 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3395 uint8 channelAuraMask = 0;
3396 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3398 channelAuraMask |= 1 << i;
3399
3400 channelAuraMask &= channelTargetEffectMask;
3401
3402 float range = 0;
3403 if (channelAuraMask)
3404 {
3406 if (range == 0)
3407 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3408 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3409 {
3410 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3411 break;
3412 }
3413
3414 if (Player* modOwner = m_caster->GetSpellModOwner())
3415 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3416
3417 // xinef: add little tolerance level
3418 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3419 }
3420
3421 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3422 {
3423 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3424 {
3425 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3426
3427 if (!unit)
3428 continue;
3429
3430 if (IsValidDeadOrAliveTarget(unit))
3431 {
3432 if (channelAuraMask & ihit->effectMask)
3433 {
3435 {
3436 if (m_caster != unit)
3437 {
3438 if (!m_caster->IsWithinDistInMap(unit, range))
3439 {
3440 ihit->effectMask &= ~aurApp->GetEffectMask();
3441 unit->RemoveAura(aurApp);
3442 continue;
3443 }
3444 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3447 }
3448 }
3449 else // aura is dispelled
3450 continue;
3451 }
3452
3453 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3454 }
3455 }
3456 }
3457
3458 // Xinef: not all effects are covered, remove applications from all targets
3459 if (channelTargetEffectMask != 0)
3460 {
3461 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3462 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3463 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3464 if (IsValidDeadOrAliveTarget(unit))
3466 {
3467 ihit->effectMask &= ~aurApp->GetEffectMask();
3468 unit->RemoveAura(aurApp);
3469 }
3470 }
3471
3472 // is all effects from m_needAliveTargetMask have alive targets
3473 return channelTargetEffectMask == 0;
3474}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition: SharedDefines.h:433
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1321
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition: Unit.cpp:5562
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition: Unit.cpp:20059
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition: Spell.cpp:8224

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, SpellInfo::IsPositive(), IsValidDeadOrAliveTarget(), WorldObject::IsWithinDistInMap(), m_caster, m_channelTargetEffectMask, m_originalCasterGUID, m_spellInfo, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, Unit::RemoveAura(), SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL, SPELL_EFFECT_APPLY_AURA, SPELL_MISS_NONE, SPELLMOD_RANGE, and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
7863{
7866 else
7867 {
7870 m_originalCaster = nullptr;
7871 }
7872
7874 {
7876 // cast item not found, somehow the item is no longer where we expected
7877 if (!m_CastItem)
7878 return false;
7879 }
7880 else
7881 m_CastItem = nullptr;
7882
7884
7885 // further actions done only for dest targets
7886 if (!m_targets.HasDst())
7887 return true;
7888
7889 // cache last transport
7890 WorldObject* transport = nullptr;
7891
7892 // update effect destinations (in case of moved transport dest target)
7893 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7894 {
7895 SpellDestination& dest = m_destTargets[effIndex];
7896 if (!dest._transportGUID)
7897 continue;
7898
7899 if (!transport || transport->GetGUID() != dest._transportGUID)
7901
7902 if (transport)
7903 {
7904 dest._position.Relocate(transport);
7906 }
7907 }
7908
7909 return true;
7910}
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:115
void RelocateOffset(const Position &offset)
Definition: Position.cpp:59
Position _transportOffset
Definition: Spell.h:107
ObjectGuid _transportGUID
Definition: Spell.h:106
void Update(Unit *caster)
Definition: Spell.cpp:479

References SpellDestination::_position, SpellDestination::_transportGUID, SpellDestination::_transportOffset, Object::GetGUID(), Player::GetItemByGuid(), ObjectAccessor::GetUnit(), ObjectAccessor::GetWorldObject(), SpellCastTargets::HasDst(), Object::IsInWorld(), Object::IsPlayer(), m_caster, m_CastItem, m_castItemGUID, m_destTargets, m_originalCaster, m_originalCasterGUID, m_targets, MAX_SPELL_EFFECTS, Position::Relocate(), Position::RelocateOffset(), Object::ToPlayer(), and SpellCastTargets::Update().

Referenced by _cast(), handle_delayed(), and update().

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket data)
4930{
4931 uint32 ammoInventoryType = 0;
4932 uint32 ammoDisplayID = 0;
4933
4934 if (m_caster->IsPlayer())
4935 {
4937 if (pItem)
4938 {
4939 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4940 if (ammoInventoryType == INVTYPE_THROWN)
4941 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4942 else
4943 {
4945 if (ammoID)
4946 {
4947 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4948 if (pProto)
4949 {
4950 ammoDisplayID = pProto->DisplayInfoID;
4951 ammoInventoryType = pProto->InventoryType;
4952 }
4953 }
4954 else if (m_caster->HasAura(46699)) // Requires No Ammo
4955 {
4956 ammoDisplayID = 5996; // normal arrow
4957 ammoInventoryType = INVTYPE_AMMO;
4958 }
4959 }
4960 }
4961 }
4962 else
4963 {
4964 uint32 nonRangedAmmoDisplayID = 0;
4965 uint32 nonRangedAmmoInventoryType = 0;
4966 for (uint8 i = 0; i < 3; ++i)
4967 {
4969 {
4970 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4971 {
4972 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4973 {
4974 switch (itemEntry->SubclassID)
4975 {
4977 ammoDisplayID = itemEntry->DisplayInfoID;
4978 ammoInventoryType = itemEntry->InventoryType;
4979 break;
4982 ammoDisplayID = 5996; // is this need fixing?
4983 ammoInventoryType = INVTYPE_AMMO;
4984 break;
4986 ammoDisplayID = 5998; // is this need fixing?
4987 ammoInventoryType = INVTYPE_AMMO;
4988 break;
4989 default:
4990 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4991 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4992 break;
4993 }
4994
4995 if (ammoDisplayID)
4996 break;
4997 }
4998 }
4999 }
5000 }
5001
5002 if (!ammoDisplayID && !ammoInventoryType)
5003 {
5004 ammoDisplayID = nonRangedAmmoDisplayID;
5005 ammoInventoryType = nonRangedAmmoInventoryType;
5006 }
5007 }
5008
5009 *data << uint32(ammoDisplayID);
5010 *data << uint32(ammoInventoryType);
5011}
@ INVTYPE_AMMO
Definition: ItemTemplate.h:280
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition: UpdateFields.h:116
DBCStorage< ItemEntry > sItemStore(Itemfmt)
uint32 DisplayInfoID
Definition: ItemTemplate.h:625
Definition: DBCStructure.h:1139

References ItemTemplate::DisplayInfoID, Item::GetTemplate(), Object::GetUInt32Value(), Player::GetWeaponForAttack(), Unit::HasAura(), ItemTemplate::InventoryType, INVTYPE_AMMO, INVTYPE_THROWN, Object::IsPlayer(), ITEM_CLASS_WEAPON, ITEM_SUBCLASS_WEAPON_BOW, ITEM_SUBCLASS_WEAPON_CROSSBOW, ITEM_SUBCLASS_WEAPON_GUN, ITEM_SUBCLASS_WEAPON_THROWN, m_caster, PLAYER_AMMO_ID, RANGED_ATTACK, sItemStore, sObjectMgr, Object::ToPlayer(), and UNIT_VIRTUAL_ITEM_SLOT_ID.

Referenced by SendSpellGo(), and SendSpellStart().

◆ WriteCastResultInfo()

void Spell::WriteCastResultInfo ( WorldPacket data,
Player caster,
SpellInfo const *  spellInfo,
uint8  castCount,
SpellCastResult  result,
SpellCustomErrors  customError 
)
static
4566{
4567 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4568 data << uint32(spellInfo->Id);
4569 data << uint8(result); // problem
4570 switch (result)
4571 {
4573 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4574 break;
4575 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4576 // hardcode areas limitation case
4577 switch (spellInfo->Id)
4578 {
4579 case 41617: // Cenarion Mana Salve
4580 case 41619: // Cenarion Healing Salve
4581 data << uint32(3905);
4582 break;
4583 case 41618: // Bottled Nethergon Energy
4584 case 41620: // Bottled Nethergon Vapor
4585 data << uint32(3842);
4586 break;
4587 case 45373: // Bloodberry Elixir
4588 data << uint32(4075);
4589 break;
4590 default: // default case (don't must be)
4591 data << uint32(0);
4592 break;
4593 }
4594 break;
4596 if (spellInfo->Totem[0])
4597 data << uint32(spellInfo->Totem[0]);
4598 if (spellInfo->Totem[1])
4599 data << uint32(spellInfo->Totem[1]);
4600 break;
4602 if (spellInfo->TotemCategory[0])
4603 data << uint32(spellInfo->TotemCategory[0]);
4604 if (spellInfo->TotemCategory[1])
4605 data << uint32(spellInfo->TotemCategory[1]);
4606 break;
4610 data << uint32(spellInfo->EquippedItemClass);
4611 data << uint32(spellInfo->EquippedItemSubClassMask);
4612 break;
4614 {
4615 uint32 item = 0;
4616 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4617 if (spellInfo->Effects[eff].ItemType)
4618 item = spellInfo->Effects[eff].ItemType;
4619 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4620 if (proto && proto->ItemLimitCategory)
4621 data << uint32(proto->ItemLimitCategory);
4622 break;
4623 }
4625 data << uint32(customError);
4626 break;
4628 {
4629 uint32 missingItem = 0;
4630 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4631 {
4632 if (spellInfo->Reagent[i] <= 0)
4633 continue;
4634
4635 uint32 itemid = spellInfo->Reagent[i];
4636 uint32 itemcount = spellInfo->ReagentCount[i];
4637
4638 if (!caster->HasItemCount(itemid, itemcount))
4639 {
4640 missingItem = itemid;
4641 break;
4642 }
4643 }
4644
4645 data << uint32(missingItem); // first missing item
4646 break;
4647 }
4649 data << uint32(spellInfo->Mechanic);
4650 break;
4652 data << uint32(spellInfo->EquippedItemSubClassMask);
4653 break;
4655 data << uint32(0); // Item entry
4656 data << uint32(0); // Count
4657 break;
4659 data << uint32(0); // SkillLine.dbc Id
4660 data << uint32(0); // Amount
4661 break;
4663 data << uint32(0); // Skill level
4664 break;
4665 default:
4666 break;
4667 }
4668}
@ SPELL_FAILED_NEED_EXOTIC_AMMO
Definition: SharedDefines.h:1003
@ SPELL_FAILED_FISHING_TOO_LOW
Definition: SharedDefines.h:1130
@ SPELL_FAILED_MIN_SKILL
Definition: SharedDefines.h:1099
@ SPELL_FAILED_PREVENTED_BY_MECHANIC
Definition: SharedDefines.h:1096
@ SPELL_FAILED_REQUIRES_AREA
Definition: SharedDefines.h:1050

References SpellInfo::Effects, SpellInfo::EquippedItemClass, SpellInfo::EquippedItemSubClassMask, Player::HasItemCount(), SpellInfo::Id, ItemTemplate::ItemLimitCategory, MAX_SPELL_EFFECTS, MAX_SPELL_REAGENTS, SpellInfo::Mechanic, SpellInfo::Reagent, SpellInfo::ReagentCount, SpellInfo::RequiresSpellFocus, sObjectMgr, SPELL_FAILED_CUSTOM_ERROR, SPELL_FAILED_EQUIPPED_ITEM_CLASS, SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND, SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND, SPELL_FAILED_FISHING_TOO_LOW, SPELL_FAILED_MIN_SKILL, SPELL_FAILED_NEED_EXOTIC_AMMO, SPELL_FAILED_NEED_MORE_ITEMS, SPELL_FAILED_PREVENTED_BY_MECHANIC, SPELL_FAILED_REAGENTS, SPELL_FAILED_REQUIRES_AREA, SPELL_FAILED_REQUIRES_SPELL_FOCUS, SPELL_FAILED_TOO_MANY_OF_ITEM, SPELL_FAILED_TOTEM_CATEGORY, SPELL_FAILED_TOTEMS, SpellInfo::Totem, and SpellInfo::TotemCategory.

Referenced by SendCastResult(), and SendPetCastResult().

◆ WriteSpellGoTargets()

void Spell::WriteSpellGoTargets ( WorldPacket data)

Writes miss and hit targets for a SMSG_SPELL_GO packet.

5015{
5016 // This function also fill data for channeled spells:
5017 // m_needAliveTargetMask req for stop channelig if one target die
5018 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5019 {
5020 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5021 // possibly SPELL_MISS_IMMUNE2 for this??
5022 ihit->missCondition = SPELL_MISS_IMMUNE2;
5023 }
5024
5025 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5026 // sending more than 255 targets crashes the client (since count sent would be wrong)
5027 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5028 // target conditions but we still need to limit the number of targets sent and keeping
5029 // correct count for both hit and miss).
5030
5031 uint32 hit = 0;
5032 std::size_t hitPos = data->wpos();
5033 *data << (uint8)0; // placeholder
5034 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5035 {
5036 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5037 {
5038 *data << ihit->targetGUID;
5039 // Xinef: No channeled spell checked, no anything
5040 //m_channelTargetEffectMask |=ihit->effectMask;
5041 ++hit;
5042 }
5043 }
5044
5045 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5046 {
5047 *data << ighit->targetGUID; // Always hits
5048 ++hit;
5049 }
5050
5051 uint32 miss = 0;
5052 std::size_t missPos = data->wpos();
5053 *data << (uint8)0; // placeholder
5054 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5055 {
5056 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5057 {
5058 *data << ihit->targetGUID;
5059 *data << uint8(ihit->missCondition);
5060 if (ihit->missCondition == SPELL_MISS_REFLECT)
5061 *data << uint8(ihit->reflectResult);
5062 ++miss;
5063 }
5064 }
5065 // Reset m_needAliveTargetMask for non channeled spell
5066 // Xinef: Why do we reset something that is not set??????
5067 //if (!m_spellInfo->IsChanneled())
5068 // m_channelTargetEffectMask = 0;
5069
5070 data->put<uint8>(hitPos, (uint8)hit);
5071 data->put<uint8>(missPos, (uint8)miss);
5072}
std::size_t wpos() const
Definition: ByteBuffer.h:330
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:137

References m_UniqueGOTargetInfo, m_UniqueTargetInfo, ByteBuffer::put(), SPELL_MISS_IMMUNE2, SPELL_MISS_NONE, SPELL_MISS_REFLECT, and ByteBuffer::wpos().

Referenced by SendSpellGo().

Friends And Related Function Documentation

◆ SpellScript

friend class SpellScript
friend

◆ Unit::SetCurrentCastedSpell

void Unit::SetCurrentCastedSpell ( Spell pSpell)
friend

Member Data Documentation

◆ _scriptsLoaded

bool Spell::_scriptsLoaded
protected

Referenced by LoadScripts(), and Spell().

◆ _spellEvent

SpellEvent* Spell::_spellEvent
protected

◆ _spellTargetsSelected

bool Spell::_spellTargetsSelected
protected

Referenced by _cast(), prepare(), and Spell().

◆ _triggeredCastFlags

TriggerCastFlags Spell::_triggeredCastFlags
protected

◆ damage

◆ destTarget

◆ effectHandleMode

SpellEffectHandleMode Spell::effectHandleMode
protected

Referenced by EffectActivateObject(), EffectActivateRune(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddFarsight(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDestroyAllTotems(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectDamage(), EffectGameObjectRepair(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectSkill(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectSpiritHeal(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), HandleEffects(), and Spell().

◆ focusObject

◆ gameObjTarget

◆ itemTarget

◆ m_appliedMods

◆ m_applyMultiplierMask

uint8 Spell::m_applyMultiplierMask
protected

◆ m_attackType

◆ m_auraScaleMask

uint8 Spell::m_auraScaleMask
protected

◆ m_autoRepeat

bool Spell::m_autoRepeat
protected

◆ m_canReflect

bool Spell::m_canReflect
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_cast_count

◆ m_caster

Unit* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectCharge(), EffectChargeDest(), EffectDestroyAllTotems(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectRepair(), EffectHeal(), EffectHealMaxHealth(), EffectHealthLeech(), EffectInstaKill(), EffectJump(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectModifyThreatPercent(), EffectOpenLock(), EffectParry(), EffectPersistentAA(), EffectPickPocket(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTradeSkill(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), finish(), GetCaster(), handle_delayed(), handle_immediate(), HandleLaunchPhase(), HandleThreatSpells(), HasGlobalCooldown(), InitExplicitTargets(), IsChannelActive(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), RecalculateDelayMomentForDst(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitCasterObjectTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTrajTargets(), SendCastResult(), SendChannelStart(), SendChannelUpdate(), SendInterrupted(), SendLogExecute(), SendLoot(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Spell(), SummonGuardian(), TakeAmmo(), TakeCastItem(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), UpdateChanneledTargetList(), UpdatePointers(), and WriteAmmoToPacket().

◆ m_CastItem

◆ m_castItemGUID

◆ m_casttime

◆ m_channeledDuration

int32 Spell::m_channeledDuration
protected

◆ m_channelTargetEffectMask

uint8 Spell::m_channelTargetEffectMask
protected

◆ m_comboPointGain

int8 Spell::m_comboPointGain

◆ m_comboTarget

Unit* Spell::m_comboTarget

◆ m_customError

◆ m_damage

◆ m_damageMultipliers

float Spell::m_damageMultipliers[3]
protected

◆ m_delayAtDamageCount

uint8 Spell::m_delayAtDamageCount
protected

Referenced by isDelayableNoMore(), and Spell().

◆ m_delayMoment

◆ m_delayStart

uint64 Spell::m_delayStart
protected

Referenced by GetDelayStart(), SetDelayStart(), and Spell().

◆ m_delayTrajectory

uint64 Spell::m_delayTrajectory
protected

◆ m_destTargets

SpellDestination Spell::m_destTargets[MAX_SPELL_EFFECTS]
protected

◆ m_diminishGroup

DiminishingGroup Spell::m_diminishGroup
protected

◆ m_diminishLevel

DiminishingLevels Spell::m_diminishLevel
protected

◆ m_effectExecuteData

◆ m_executedCurrently

bool Spell::m_executedCurrently
protected

◆ m_glyphIndex

uint32 Spell::m_glyphIndex

◆ m_healing

◆ m_hitTriggerSpells

HitTriggerSpellList Spell::m_hitTriggerSpells
protected

◆ m_immediateHandled

bool Spell::m_immediateHandled
protected

Referenced by _cast(), handle_delayed(), and Spell().

◆ m_loadedScripts

◆ m_needComboPoints

bool Spell::m_needComboPoints
protected

◆ m_originalCaster

◆ m_originalCasterGUID

◆ m_powerCost

◆ m_preCastSpell

uint32 Spell::m_preCastSpell

◆ m_preGeneratedPath

std::unique_ptr<PathGenerator> Spell::m_preGeneratedPath
protected

Referenced by CheckCast(), and EffectCharge().

◆ m_procAttacker

uint32 Spell::m_procAttacker
protected

◆ m_procEx

uint32 Spell::m_procEx
protected

◆ m_procVictim

uint32 Spell::m_procVictim
protected

◆ m_referencedFromCurrentSpell

bool Spell::m_referencedFromCurrentSpell
protected

◆ m_runesState

uint8 Spell::m_runesState
protected

◆ m_selfContainer

Spell** Spell::m_selfContainer
protected

◆ m_skipCheck

bool Spell::m_skipCheck
protected

Referenced by AddUnitTarget(), and Spell().

◆ m_spellAura

◆ m_spellFlags

◆ m_spellInfo

SpellInfo const* const Spell::m_spellInfo

Referenced by _cast(), _handle_finish_phase(), _handle_immediate_phase(), Unit::_UpdateAutoRepeatSpell(), AddGOTarget(), AddItemTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateJumpSpeeds(), CalculateSpellDamage(), CallScriptDestinationTargetSelectHandlers(), CallScriptEffectHandlers(), CallScriptObjectAreaTargetSelectHandlers(), CallScriptObjectTargetSelectHandlers(), CanAutoCast(), cancel(), CancelGlobalCooldown(), CanExecuteTriggersOnHit(), CanOpenLock(), CheckCast(), CheckCasterAuras(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckScriptEffectImplicitTargets(), CheckSpellFocus(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectAddHonor(), EffectApplyGlyph(), EffectBind(), EffectCastButtons(), EffectCharge(), EffectCreateItem(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectFeedPet(), EffectForceCast(), EffectForceDeselect(), EffectGameObjectSetDestructionState(), EffectHeal(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInstaKill(), EffectInterruptCast(), EffectJumpDest(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectOpenLock(), EffectPersistentAA(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectProficiency(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRemoveAura(), EffectReputation(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSendTaxi(), EffectStealBeneficialBuff(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectSummonPet(), EffectSummonType(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectWeaponDmg(), finish(), GetCurrentContainer(), GetSearcherTypeMask(), GetSpellInfo(), handle_immediate(), WorldSession::HandleCastSpellOpcode(), HandleEffects(), HandleLaunchPhase(), WorldSession::HandlePetCastSpellOpcode(), HandleThreatSpells(), WorldSession::HandleUpdateMissileTrajectory(), HasGlobalCooldown(), InitExplicitTargets(), IsAutoActionResetSpell(), IsNeedSendToClient(), IsNextMeleeSwingSpell(), IsValidDeadOrAliveTarget(), LoadScripts(), OnSpellLaunch(), prepare(), prepareDataForTriggerSystem(), PrepareTriggersExecutedOnHit(), Player::RemoveSpellMods(), Player::RestoreSpellMods(), SearchAreaTargets(), SearchChainTargets(), SearchNearbyTarget(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChainTargets(), SelectImplicitChannelTargets(), SelectImplicitConeTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendCastResult(), SendChannelStart(), SendInterrupted(), SendLogExecute(), SendPetCastResult(), SendResurrectRequest(), SendSpellCooldown(), SendSpellGo(), SendSpellStart(), Unit::SetCurrentCastedSpell(), Player::SetSpellModTakingSpell(), SetSpellValue(), Spell(), SummonGuardian(), TakePower(), TakeReagents(), TakeRunePower(), TriggerGlobalCooldown(), update(), PetAI::UpdateAI(), UpdateChanneledTargetList(), Player::UpdatePotionCooldown(), ~Spell(), and SpellEvent::~SpellEvent().

◆ m_spellSchoolMask

◆ m_spellState

uint32 Spell::m_spellState
protected

◆ m_spellValue

◆ m_targets

SpellCastTargets Spell::m_targets

Referenced by _cast(), CalculateDelayMomentForDst(), CheckCast(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckRange(), CheckSrc(), Unit::DealDamage(), DoAllEffectOnTarget(), DoSpellHitOnUnit(), EffectBind(), EffectChargeDest(), EffectEnchantItemPerm(), EffectJumpDest(), EffectKnockBack(), EffectLeap(), EffectPullTowards(), EffectSummonChangeItem(), EffectSummonObject(), EffectSummonObjectWild(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerSpell(), SpellScript::GetExplTargetDest(), SpellScript::GetExplTargetGObj(), SpellScript::GetExplTargetItem(), SpellScript::GetExplTargetUnit(), SpellScript::GetExplTargetWorldObject(), handle_delayed(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), spell_vehicle_throw_passenger::HandleScript(), WorldSession::HandleUpdateMissileTrajectory(), WorldSession::HandleUpdateProjectilePosition(), InitExplicitTargets(), spell_ioc_launch::Launch(), OnSpellLaunch(), prepare(), SelectEffectImplicitTargets(), SelectEffectTypeImplicitTargets(), SelectExplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitCasterDestTargets(), SelectImplicitChannelTargets(), SelectImplicitDestDestTargets(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), SelectImplicitTargetObjectTargets(), SelectImplicitTrajTargets(), SelectSpellTargets(), SendChannelStart(), SendSpellGo(), SendSpellStart(), SpellScript::SetExplTargetDest(), TakeCastItem(), TakePower(), TakeReagents(), update(), and UpdatePointers().

◆ m_timer

◆ m_triggeredByAuraSpell

◆ m_UniqueGOTargetInfo

◆ m_UniqueItemInfo

◆ m_UniqueTargetInfo

◆ m_weaponItem

Item* Spell::m_weaponItem

◆ unitTarget

Unit* Spell::unitTarget
protected

Referenced by CheckCast(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), EffectActivateSpec(), EffectAddComboPoints(), EffectAddExtraAttacks(), EffectAddHonor(), EffectApplyAreaAura(), EffectApplyAura(), EffectBind(), EffectCharge(), EffectCreateItem2(), EffectCreateRandomItem(), EffectCreateTamedPet(), EffectDiscoverTaxi(), EffectDismissPet(), EffectDispel(), EffectDispelMechanic(), EffectDistract(), EffectDualWield(), EffectDuel(), EffectDummy(), EffectDurabilityDamage(), EffectDurabilityDamagePCT(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnergize(), EffectEnergizePct(), EffectEnvironmentalDMG(), EffectForceCast(), EffectHeal(), EffectHealMaxHealth(), EffectHealMechanical(), EffectHealPct(), EffectHealthLeech(), EffectInebriate(), EffectInstaKill(), EffectInterruptCast(), EffectJump(), EffectKillCredit(), EffectKillCreditPersonal(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnPetSpell(), EffectLearnSkill(), EffectLearnSpell(), EffectModifyThreatPercent(), EffectPickPocket(), EffectPlayMusic(), EffectPlaySound(), EffectPowerBurn(), EffectPowerDrain(), EffectPullTowards(), EffectQuestClear(), EffectQuestComplete(), EffectQuestFail(), EffectQuestStart(), EffectRechargeManaGem(), EffectRedirectThreat(), EffectRemoveAura(), EffectRenamePet(), EffectReputation(), EffectResurrect(), EffectResurrectNew(), EffectSanctuary(), EffectSchoolDMG(), EffectScriptEffect(), EffectSendEvent(), EffectSendTaxi(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectSpecCount(), EffectStealBeneficialBuff(), EffectSummonPlayer(), EffectSummonRaFFriend(), EffectTameCreature(), EffectTaunt(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectThreat(), EffectTitanGrip(), EffectTriggerMissileSpell(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), EffectWeaponDmg(), SpellScript::GetHitCreature(), SpellScript::GetHitPlayer(), SpellScript::GetHitUnit(), HandleEffects(), SelectEffectTypeImplicitTargets(), SelectImplicitAreaTargets(), SelectImplicitChainTargets(), SelectImplicitTrajTargets(), and Spell().